mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-27 07:34:15 +02:00
parent
c3cf7682b9
commit
873e294158
@ -205,8 +205,9 @@ int Main(void)
|
|||||||
String initconfig = Application::GetSysconfDir() + "/icinga2/init.conf";
|
String initconfig = Application::GetSysconfDir() + "/icinga2/init.conf";
|
||||||
|
|
||||||
if (Utility::PathExists(initconfig)) {
|
if (Utility::PathExists(initconfig)) {
|
||||||
ConfigCompilerContext::GetInstance()->Reset();
|
ScriptFrame frame;
|
||||||
ConfigCompiler::CompileFile(initconfig);
|
Expression *expression = ConfigCompiler::CompileFile(initconfig);
|
||||||
|
expression->Evaluate(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -27,7 +27,7 @@ set(base_SOURCES
|
|||||||
convert.cpp debuginfo.cpp dictionary.cpp dictionary-script.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
|
convert.cpp debuginfo.cpp dictionary.cpp dictionary-script.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
|
||||||
exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp logger.cpp logger.thpp
|
exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp logger.cpp logger.thpp
|
||||||
netstring.cpp networkstream.cpp number.cpp number-script.cpp object.cpp object-script.cpp primitivetype.cpp process.cpp
|
netstring.cpp networkstream.cpp number.cpp number-script.cpp object.cpp object-script.cpp primitivetype.cpp process.cpp
|
||||||
ringbuffer.cpp scripterror.cpp scriptframe.cpp scriptfunction.cpp scriptfunctionwrapper.cpp scriptglobal.cpp
|
ringbuffer.cpp scriptframe.cpp scriptfunction.cpp scriptfunctionwrapper.cpp scriptglobal.cpp
|
||||||
scriptutils.cpp serializer.cpp socket.cpp stacktrace.cpp
|
scriptutils.cpp serializer.cpp socket.cpp stacktrace.cpp
|
||||||
statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp string-script.cpp
|
statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp string-script.cpp
|
||||||
sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp thinmutex.cpp threadpool.cpp timer.cpp
|
sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp thinmutex.cpp threadpool.cpp timer.cpp
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "base/initialize.hpp"
|
#include "base/initialize.hpp"
|
||||||
#include "base/workqueue.hpp"
|
#include "base/workqueue.hpp"
|
||||||
#include "base/context.hpp"
|
#include "base/context.hpp"
|
||||||
|
#include "base/application.hpp"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/exception/errinfo_api_function.hpp>
|
#include <boost/exception/errinfo_api_function.hpp>
|
||||||
@ -310,7 +311,7 @@ void DynamicObject::RestoreObjects(const String& filename, int attributeTypes)
|
|||||||
|
|
||||||
unsigned long restored = 0;
|
unsigned long restored = 0;
|
||||||
|
|
||||||
ParallelWorkQueue upq;
|
WorkQueue upq(25000, Application::GetConcurrency());
|
||||||
|
|
||||||
String message;
|
String message;
|
||||||
while (NetString::ReadStringFromStream(sfp, &message)) {
|
while (NetString::ReadStringFromStream(sfp, &message)) {
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "base/debug.hpp"
|
#include "base/debug.hpp"
|
||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
#include "base/convert.hpp"
|
#include "base/convert.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
|
@ -153,3 +153,24 @@ String icinga::DiagnosticInformation(boost::exception_ptr eptr)
|
|||||||
return boost::diagnostic_information(eptr);
|
return boost::diagnostic_information(eptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScriptError::ScriptError(const String& message)
|
||||||
|
: m_Message(message)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
ScriptError::ScriptError(const String& message, const DebugInfo& di)
|
||||||
|
: m_Message(message), m_DebugInfo(di)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
ScriptError::~ScriptError(void) throw()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
const char *ScriptError::what(void) const throw()
|
||||||
|
{
|
||||||
|
return m_Message.CStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugInfo ScriptError::GetDebugInfo(void) const
|
||||||
|
{
|
||||||
|
return m_DebugInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "base/stacktrace.hpp"
|
#include "base/stacktrace.hpp"
|
||||||
#include "base/context.hpp"
|
#include "base/context.hpp"
|
||||||
#include "base/utility.hpp"
|
#include "base/utility.hpp"
|
||||||
|
#include "base/debuginfo.hpp"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <boost/exception/errinfo_api_function.hpp>
|
#include <boost/exception/errinfo_api_function.hpp>
|
||||||
#include <boost/exception/errinfo_errno.hpp>
|
#include <boost/exception/errinfo_errno.hpp>
|
||||||
@ -42,6 +43,25 @@ namespace icinga
|
|||||||
class I2_BASE_API user_error : virtual public std::exception, virtual public boost::exception
|
class I2_BASE_API user_error : virtual public std::exception, virtual public boost::exception
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @ingroup base
|
||||||
|
*/
|
||||||
|
class I2_BASE_API ScriptError : virtual public user_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScriptError(const String& message);
|
||||||
|
ScriptError(const String& message, const DebugInfo& di);
|
||||||
|
~ScriptError(void) throw();
|
||||||
|
|
||||||
|
virtual const char *what(void) const throw();
|
||||||
|
|
||||||
|
DebugInfo GetDebugInfo(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
String m_Message;
|
||||||
|
DebugInfo m_DebugInfo;
|
||||||
|
};
|
||||||
|
|
||||||
I2_BASE_API StackTrace *GetLastExceptionStack(void);
|
I2_BASE_API StackTrace *GetLastExceptionStack(void);
|
||||||
I2_BASE_API void SetLastExceptionStack(const StackTrace& trace);
|
I2_BASE_API void SetLastExceptionStack(const StackTrace& trace);
|
||||||
|
|
||||||
@ -58,9 +78,23 @@ String DiagnosticInformation(const T& ex, StackTrace *stack = NULL, ContextTrace
|
|||||||
{
|
{
|
||||||
std::ostringstream result;
|
std::ostringstream result;
|
||||||
|
|
||||||
result << boost::diagnostic_information(ex);
|
const user_error *uex = dynamic_cast<const user_error *>(&ex);
|
||||||
|
|
||||||
if (dynamic_cast<const user_error *>(&ex) == NULL) {
|
String message = ex.what();
|
||||||
|
|
||||||
|
if (!uex || message.IsEmpty())
|
||||||
|
result << boost::diagnostic_information(ex);
|
||||||
|
else
|
||||||
|
result << "Error: " << message;
|
||||||
|
|
||||||
|
const ScriptError *dex = dynamic_cast<const ScriptError *>(&ex);
|
||||||
|
|
||||||
|
if (dex && !dex->GetDebugInfo().Path.IsEmpty()) {
|
||||||
|
result << "\nLocation:\n";
|
||||||
|
ShowCodeFragment(result, dex->GetDebugInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uex) {
|
||||||
if (boost::get_error_info<StackTraceErrorInfo>(ex) == NULL) {
|
if (boost::get_error_info<StackTraceErrorInfo>(ex) == NULL) {
|
||||||
result << std::endl;
|
result << std::endl;
|
||||||
|
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* Icinga 2 *
|
|
||||||
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU General Public License *
|
|
||||||
* as published by the Free Software Foundation; either version 2 *
|
|
||||||
* of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* This program is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
||||||
* GNU General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU General Public License *
|
|
||||||
* along with this program; if not, write to the Free Software Foundation *
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include "base/scripterror.hpp"
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
using namespace icinga;
|
|
||||||
|
|
||||||
ScriptError::ScriptError(const String& message)
|
|
||||||
: m_Message(message)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
ScriptError::ScriptError(const String& message, const DebugInfo& di)
|
|
||||||
: m_Message(message), m_DebugInfo(di)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
ScriptError::~ScriptError(void) throw()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
const char *ScriptError::what(void) const throw()
|
|
||||||
{
|
|
||||||
return m_Message.CStr();
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugInfo ScriptError::GetDebugInfo(void) const
|
|
||||||
{
|
|
||||||
return m_DebugInfo;
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* Icinga 2 *
|
|
||||||
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
|
|
||||||
* *
|
|
||||||
* This program is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU General Public License *
|
|
||||||
* as published by the Free Software Foundation; either version 2 *
|
|
||||||
* of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* This program is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
||||||
* GNU General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU General Public License *
|
|
||||||
* along with this program; if not, write to the Free Software Foundation *
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SCRIPTERROR_H
|
|
||||||
#define SCRIPTERROR_H
|
|
||||||
|
|
||||||
#include "base/i2-base.hpp"
|
|
||||||
#include "base/debuginfo.hpp"
|
|
||||||
#include "base/exception.hpp"
|
|
||||||
|
|
||||||
namespace icinga
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @ingroup base
|
|
||||||
*/
|
|
||||||
class I2_BASE_API ScriptError : virtual public user_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ScriptError(const String& message);
|
|
||||||
ScriptError(const String& message, const DebugInfo& di);
|
|
||||||
~ScriptError(void) throw();
|
|
||||||
|
|
||||||
virtual const char *what(void) const throw();
|
|
||||||
|
|
||||||
DebugInfo GetDebugInfo(void) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
String m_Message;
|
|
||||||
DebugInfo m_DebugInfo;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SCRIPTERROR_H */
|
|
@ -26,7 +26,7 @@
|
|||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
#include "base/dynamictype.hpp"
|
#include "base/dynamictype.hpp"
|
||||||
#include "base/application.hpp"
|
#include "base/application.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/regex.hpp>
|
#include <boost/regex.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -22,16 +22,19 @@
|
|||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/convert.hpp"
|
#include "base/convert.hpp"
|
||||||
#include "base/application.hpp"
|
#include "base/application.hpp"
|
||||||
|
#include "base/exception.hpp"
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/thread/tss.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
int WorkQueue::m_NextID = 1;
|
int WorkQueue::m_NextID = 1;
|
||||||
|
boost::thread_specific_ptr<WorkQueue *> l_ThreadWorkQueue;
|
||||||
|
|
||||||
WorkQueue::WorkQueue(size_t maxItems)
|
WorkQueue::WorkQueue(size_t maxItems, int threadCount)
|
||||||
: m_ID(m_NextID++), m_MaxItems(maxItems), m_Stopped(false),
|
: m_ID(m_NextID++), m_MaxItems(maxItems), m_ThreadCount(threadCount), m_Spawned(false), m_Stopped(false),
|
||||||
m_Processing(false), m_ExceptionCallback(WorkQueue::DefaultExceptionCallback)
|
m_Processing(0)
|
||||||
{
|
{
|
||||||
m_StatusTimer = new Timer();
|
m_StatusTimer = new Timer();
|
||||||
m_StatusTimer->SetInterval(10);
|
m_StatusTimer->SetInterval(10);
|
||||||
@ -45,46 +48,53 @@ WorkQueue::~WorkQueue(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueues a work item. Work items are guaranteed to be executed in the order
|
* Enqueues a task. Tasks are guaranteed to be executed in the order
|
||||||
* they were enqueued in except when allowInterleaved is true in which case
|
* they were enqueued in except if there is more than one worker thread or when
|
||||||
* the new work item might be run immediately if it's being enqueued from
|
* allowInterleaved is true in which case the new task might be run
|
||||||
* within the WorkQueue thread.
|
* immediately if it's being enqueued from within the WorkQueue thread.
|
||||||
*/
|
*/
|
||||||
void WorkQueue::Enqueue(const WorkCallback& callback, bool allowInterleaved)
|
void WorkQueue::Enqueue(const Task& task, bool allowInterleaved)
|
||||||
{
|
{
|
||||||
bool wq_thread = (boost::this_thread::get_id() == GetThreadId());
|
bool wq_thread = IsWorkerThread();
|
||||||
|
|
||||||
if (wq_thread && allowInterleaved) {
|
if (wq_thread && allowInterleaved) {
|
||||||
callback();
|
task();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkItem item;
|
|
||||||
item.Callback = callback;
|
|
||||||
item.AllowInterleaved = allowInterleaved;
|
|
||||||
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
if (m_Thread.get_id() == boost::thread::id())
|
if (!m_Spawned) {
|
||||||
m_Thread = boost::thread(boost::bind(&WorkQueue::WorkerThreadProc, this));
|
for (int i = 0; i < m_ThreadCount; i++) {
|
||||||
|
m_Threads.create_thread(boost::bind(&WorkQueue::WorkerThreadProc, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Spawned = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!wq_thread) {
|
if (!wq_thread) {
|
||||||
while (m_Items.size() >= m_MaxItems)
|
while (m_Tasks.size() >= m_MaxItems)
|
||||||
m_CVFull.wait(lock);
|
m_CVFull.wait(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Items.push_back(item);
|
m_Tasks.push_back(task);
|
||||||
|
|
||||||
if (m_Items.size() == 1)
|
if (m_Tasks.size() == 1)
|
||||||
m_CVEmpty.notify_all();
|
m_CVEmpty.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits until all currently enqueued tasks have completed. This only works reliably
|
||||||
|
* when no other thread is enqueuing new tasks when this method is called.
|
||||||
|
*
|
||||||
|
* @param stop Whether to stop the worker threads
|
||||||
|
*/
|
||||||
void WorkQueue::Join(bool stop)
|
void WorkQueue::Join(bool stop)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
while (m_Processing || !m_Items.empty())
|
while (m_Processing || !m_Tasks.empty())
|
||||||
m_CVStarved.wait(lock);
|
m_CVStarved.wait(lock);
|
||||||
|
|
||||||
if (stop) {
|
if (stop) {
|
||||||
@ -92,33 +102,73 @@ void WorkQueue::Join(bool stop)
|
|||||||
m_CVEmpty.notify_all();
|
m_CVEmpty.notify_all();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
if (m_Thread.joinable())
|
m_Threads.join_all();
|
||||||
m_Thread.join();
|
m_Spawned = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::thread::id WorkQueue::GetThreadId(void) const
|
/**
|
||||||
|
* Checks whether the calling thread is one of the worker threads
|
||||||
|
* for this work queue.
|
||||||
|
*
|
||||||
|
* @returns true if called from one of the worker threads, false otherwise
|
||||||
|
*/
|
||||||
|
bool WorkQueue::IsWorkerThread(void) const
|
||||||
{
|
{
|
||||||
return m_Thread.get_id();
|
WorkQueue **pwq = l_ThreadWorkQueue.get();
|
||||||
|
|
||||||
|
if (!pwq)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return *pwq == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkQueue::SetExceptionCallback(const ExceptionCallback& callback)
|
void WorkQueue::SetExceptionCallback(const ExceptionCallback& callback)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
|
||||||
|
|
||||||
m_ExceptionCallback = callback;
|
m_ExceptionCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether any exceptions have occurred while executing tasks for this
|
||||||
|
* work queue. When a custom exception callback is set this method will always
|
||||||
|
* return false.
|
||||||
|
*/
|
||||||
|
bool WorkQueue::HasExceptions(void) const
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
|
return !m_Exceptions.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all exceptions which have occurred for tasks in this work queue. When a
|
||||||
|
* custom exception callback is set this method will always return an empty list.
|
||||||
|
*/
|
||||||
|
std::vector<boost::exception_ptr> WorkQueue::GetExceptions(void) const
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
|
return m_Exceptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorkQueue::ReportExceptions(const String& facility) const
|
||||||
|
{
|
||||||
|
std::vector<boost::exception_ptr> exceptions = GetExceptions();
|
||||||
|
|
||||||
|
BOOST_FOREACH(const boost::exception_ptr& eptr, exceptions) {
|
||||||
|
Log(LogCritical, facility)
|
||||||
|
<< DiagnosticInformation(eptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log(LogCritical, facility)
|
||||||
|
<< exceptions.size() << " error" << (exceptions.size() != 1 ? "s" : "");
|
||||||
|
}
|
||||||
|
|
||||||
size_t WorkQueue::GetLength(void)
|
size_t WorkQueue::GetLength(void)
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
return m_Items.size();
|
return m_Tasks.size();
|
||||||
}
|
|
||||||
|
|
||||||
void WorkQueue::DefaultExceptionCallback(boost::exception_ptr)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkQueue::StatusTimerHandler(void)
|
void WorkQueue::StatusTimerHandler(void)
|
||||||
@ -126,7 +176,7 @@ void WorkQueue::StatusTimerHandler(void)
|
|||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
Log(LogNotice, "WorkQueue")
|
Log(LogNotice, "WorkQueue")
|
||||||
<< "#" << m_ID << " items: " << m_Items.size();
|
<< "#" << m_ID << " tasks: " << m_Tasks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkQueue::WorkerThreadProc(void)
|
void WorkQueue::WorkerThreadProc(void)
|
||||||
@ -135,67 +185,47 @@ void WorkQueue::WorkerThreadProc(void)
|
|||||||
idbuf << "WQ #" << m_ID;
|
idbuf << "WQ #" << m_ID;
|
||||||
Utility::SetThreadName(idbuf.str());
|
Utility::SetThreadName(idbuf.str());
|
||||||
|
|
||||||
|
l_ThreadWorkQueue.reset(new WorkQueue *(this));
|
||||||
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
boost::mutex::scoped_lock lock(m_Mutex);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (m_Items.empty() && !m_Stopped)
|
while (m_Tasks.empty() && !m_Stopped)
|
||||||
m_CVEmpty.wait(lock);
|
m_CVEmpty.wait(lock);
|
||||||
|
|
||||||
if (m_Stopped)
|
if (m_Stopped)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
std::deque<WorkItem> items;
|
if (m_Tasks.size() >= m_MaxItems)
|
||||||
m_Items.swap(items);
|
|
||||||
|
|
||||||
if (items.size() >= m_MaxItems)
|
|
||||||
m_CVFull.notify_all();
|
m_CVFull.notify_all();
|
||||||
|
|
||||||
m_Processing = true;
|
Task task = m_Tasks.front();
|
||||||
|
m_Tasks.pop_front();
|
||||||
|
|
||||||
|
m_Processing++;
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
BOOST_FOREACH(WorkItem& wi, items) {
|
try {
|
||||||
try {
|
task();
|
||||||
wi.Callback();
|
} catch (const std::exception&) {
|
||||||
}
|
lock.lock();
|
||||||
catch (const std::exception&) {
|
|
||||||
lock.lock();
|
|
||||||
|
|
||||||
ExceptionCallback callback = m_ExceptionCallback;
|
if (!m_ExceptionCallback)
|
||||||
|
m_Exceptions.push_back(boost::current_exception());
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
callback(boost::current_exception());
|
if (m_ExceptionCallback)
|
||||||
}
|
m_ExceptionCallback(boost::current_exception());
|
||||||
}
|
}
|
||||||
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
|
||||||
m_Processing = false;
|
m_Processing--;
|
||||||
|
|
||||||
m_CVStarved.notify_all();
|
if (m_Tasks.empty())
|
||||||
|
m_CVStarved.notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ParallelWorkQueue::ParallelWorkQueue(void)
|
|
||||||
: m_QueueCount(Application::GetConcurrency()),
|
|
||||||
m_Queues(new WorkQueue[m_QueueCount]),
|
|
||||||
m_Index(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
ParallelWorkQueue::~ParallelWorkQueue(void)
|
|
||||||
{
|
|
||||||
delete[] m_Queues;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ParallelWorkQueue::Enqueue(const boost::function<void(void)>& callback)
|
|
||||||
{
|
|
||||||
m_Index++;
|
|
||||||
m_Queues[m_Index % m_QueueCount].Enqueue(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ParallelWorkQueue::Join(void)
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < m_QueueCount; i++)
|
|
||||||
m_Queues[i].Join();
|
|
||||||
}
|
|
||||||
|
@ -32,13 +32,7 @@
|
|||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef boost::function<void (void)> WorkCallback;
|
typedef boost::function<void (void)> Task;
|
||||||
|
|
||||||
struct WorkItem
|
|
||||||
{
|
|
||||||
WorkCallback Callback;
|
|
||||||
bool AllowInterleaved;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A workqueue.
|
* A workqueue.
|
||||||
@ -50,53 +44,43 @@ class I2_BASE_API WorkQueue
|
|||||||
public:
|
public:
|
||||||
typedef boost::function<void (boost::exception_ptr)> ExceptionCallback;
|
typedef boost::function<void (boost::exception_ptr)> ExceptionCallback;
|
||||||
|
|
||||||
WorkQueue(size_t maxItems = 25000);
|
WorkQueue(size_t maxItems = 25000, int threadCount = 1);
|
||||||
~WorkQueue(void);
|
~WorkQueue(void);
|
||||||
|
|
||||||
void Enqueue(const WorkCallback& callback, bool allowInterleaved = false);
|
void Enqueue(const Task& task, bool allowInterleaved = false);
|
||||||
void Join(bool stop = false);
|
void Join(bool stop = false);
|
||||||
|
|
||||||
boost::thread::id GetThreadId(void) const;
|
bool IsWorkerThread(void) const;
|
||||||
|
|
||||||
|
size_t GetLength(void);
|
||||||
|
|
||||||
void SetExceptionCallback(const ExceptionCallback& callback);
|
void SetExceptionCallback(const ExceptionCallback& callback);
|
||||||
|
|
||||||
size_t GetLength(void);
|
bool HasExceptions(void) const;
|
||||||
|
std::vector<boost::exception_ptr> GetExceptions(void) const;
|
||||||
|
void ReportExceptions(const String& facility) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_ID;
|
int m_ID;
|
||||||
static int m_NextID;
|
static int m_NextID;
|
||||||
|
int m_ThreadCount;
|
||||||
|
bool m_Spawned;
|
||||||
|
|
||||||
boost::mutex m_Mutex;
|
mutable boost::mutex m_Mutex;
|
||||||
boost::condition_variable m_CVEmpty;
|
boost::condition_variable m_CVEmpty;
|
||||||
boost::condition_variable m_CVFull;
|
boost::condition_variable m_CVFull;
|
||||||
boost::condition_variable m_CVStarved;
|
boost::condition_variable m_CVStarved;
|
||||||
boost::thread m_Thread;
|
boost::thread_group m_Threads;
|
||||||
size_t m_MaxItems;
|
size_t m_MaxItems;
|
||||||
bool m_Stopped;
|
bool m_Stopped;
|
||||||
bool m_Processing;
|
int m_Processing;
|
||||||
std::deque<WorkItem> m_Items;
|
std::deque<Task> m_Tasks;
|
||||||
ExceptionCallback m_ExceptionCallback;
|
ExceptionCallback m_ExceptionCallback;
|
||||||
|
std::vector<boost::exception_ptr> m_Exceptions;
|
||||||
Timer::Ptr m_StatusTimer;
|
Timer::Ptr m_StatusTimer;
|
||||||
|
|
||||||
void WorkerThreadProc(void);
|
void WorkerThreadProc(void);
|
||||||
void StatusTimerHandler(void);
|
void StatusTimerHandler(void);
|
||||||
|
|
||||||
static void DefaultExceptionCallback(boost::exception_ptr exp);
|
|
||||||
};
|
|
||||||
|
|
||||||
class I2_BASE_API ParallelWorkQueue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ParallelWorkQueue(void);
|
|
||||||
~ParallelWorkQueue(void);
|
|
||||||
|
|
||||||
void Enqueue(const boost::function<void(void)>& callback);
|
|
||||||
void Join(void);
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned int m_QueueCount;
|
|
||||||
WorkQueue *m_Queues;
|
|
||||||
unsigned int m_Index;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "cli/daemoncommand.hpp"
|
#include "cli/daemoncommand.hpp"
|
||||||
#include "config/configcompilercontext.hpp"
|
|
||||||
#include "config/configcompiler.hpp"
|
#include "config/configcompiler.hpp"
|
||||||
|
#include "config/configcompilercontext.hpp"
|
||||||
#include "config/configitembuilder.hpp"
|
#include "config/configitembuilder.hpp"
|
||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/application.hpp"
|
#include "base/application.hpp"
|
||||||
@ -60,16 +60,20 @@ static String LoadAppType(const String& typeSpec)
|
|||||||
return typeSpec.SubStr(index + 1);
|
return typeSpec.SubStr(index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ExecuteExpression(Expression *expression)
|
static bool ExecuteExpression(Expression *expression)
|
||||||
{
|
{
|
||||||
|
if (!expression)
|
||||||
|
return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ScriptFrame frame;
|
ScriptFrame frame;
|
||||||
expression->Evaluate(frame);
|
expression->Evaluate(frame);
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
Log(LogCritical, "config", DiagnosticInformation(ex));
|
||||||
|
Application::Exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IncludeZoneDirRecursive(const String& path)
|
static void IncludeZoneDirRecursive(const String& path)
|
||||||
@ -95,22 +99,18 @@ static void IncludeNonLocalZone(const String& zonePath)
|
|||||||
static bool LoadConfigFiles(const boost::program_options::variables_map& vm, const String& appType,
|
static bool LoadConfigFiles(const boost::program_options::variables_map& vm, const String& appType,
|
||||||
const String& objectsFile = String(), const String& varsfile = String())
|
const String& objectsFile = String(), const String& varsfile = String())
|
||||||
{
|
{
|
||||||
ConfigCompilerContext::GetInstance()->Reset();
|
|
||||||
|
|
||||||
if (!objectsFile.IsEmpty())
|
if (!objectsFile.IsEmpty())
|
||||||
ConfigCompilerContext::GetInstance()->OpenObjectsFile(objectsFile);
|
ConfigCompilerContext::GetInstance()->OpenObjectsFile(objectsFile);
|
||||||
|
|
||||||
if (vm.count("config") > 0) {
|
if (vm.count("config") > 0) {
|
||||||
BOOST_FOREACH(const String& configPath, vm["config"].as<std::vector<std::string> >()) {
|
BOOST_FOREACH(const String& configPath, vm["config"].as<std::vector<std::string> >()) {
|
||||||
Expression *expression = ConfigCompiler::CompileFile(configPath);
|
Expression *expression = ConfigCompiler::CompileFile(configPath);
|
||||||
if (expression)
|
ExecuteExpression(expression);
|
||||||
ExecuteExpression(expression);
|
|
||||||
delete expression;
|
delete expression;
|
||||||
}
|
}
|
||||||
} else if (!vm.count("no-config")) {
|
} else if (!vm.count("no-config")) {
|
||||||
Expression *expression = ConfigCompiler::CompileFile(Application::GetSysconfDir() + "/icinga2/icinga2.conf");
|
Expression *expression = ConfigCompiler::CompileFile(Application::GetSysconfDir() + "/icinga2/icinga2.conf");
|
||||||
if (expression)
|
ExecuteExpression(expression);
|
||||||
ExecuteExpression(expression);
|
|
||||||
delete expression;
|
delete expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,8 +127,7 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||||||
String name, fragment;
|
String name, fragment;
|
||||||
BOOST_FOREACH(boost::tie(name, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) {
|
BOOST_FOREACH(boost::tie(name, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) {
|
||||||
Expression *expression = ConfigCompiler::CompileText(name, fragment);
|
Expression *expression = ConfigCompiler::CompileText(name, fragment);
|
||||||
if (expression)
|
ExecuteExpression(expression);
|
||||||
ExecuteExpression(expression);
|
|
||||||
delete expression;
|
delete expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,42 +137,7 @@ static bool LoadConfigFiles(const boost::program_options::variables_map& vm, con
|
|||||||
ConfigItem::Ptr item = builder->Compile();
|
ConfigItem::Ptr item = builder->Compile();
|
||||||
item->Register();
|
item->Register();
|
||||||
|
|
||||||
bool result = ConfigItem::ValidateItems();
|
bool result = ConfigItem::CommitItems();
|
||||||
|
|
||||||
int warnings = 0, errors = 0;
|
|
||||||
|
|
||||||
BOOST_FOREACH(const ConfigCompilerMessage& message, ConfigCompilerContext::GetInstance()->GetMessages()) {
|
|
||||||
std::ostringstream locbuf;
|
|
||||||
ShowCodeFragment(locbuf, message.Location);
|
|
||||||
String location = locbuf.str();
|
|
||||||
|
|
||||||
String logmsg;
|
|
||||||
|
|
||||||
if (!location.IsEmpty())
|
|
||||||
logmsg = "Location:\n" + location;
|
|
||||||
|
|
||||||
logmsg += String("\nConfig ") + (message.Error ? "error" : "warning") + ": " + message.Text;
|
|
||||||
|
|
||||||
if (message.Error) {
|
|
||||||
Log(LogCritical, "config", logmsg);
|
|
||||||
errors++;
|
|
||||||
} else {
|
|
||||||
Log(LogWarning, "config", logmsg);
|
|
||||||
warnings++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (warnings > 0 || errors > 0) {
|
|
||||||
LogSeverity severity;
|
|
||||||
|
|
||||||
if (errors == 0)
|
|
||||||
severity = LogWarning;
|
|
||||||
else
|
|
||||||
severity = LogCritical;
|
|
||||||
|
|
||||||
Log(severity, "config")
|
|
||||||
<< errors << " errors, " << warnings << " warnings.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "cli/replcommand.hpp"
|
#include "cli/replcommand.hpp"
|
||||||
#include "config/configcompiler.hpp"
|
#include "config/configcompiler.hpp"
|
||||||
#include "config/configcompilercontext.hpp"
|
|
||||||
#include "base/json.hpp"
|
#include "base/json.hpp"
|
||||||
#include "base/console.hpp"
|
#include "base/console.hpp"
|
||||||
#include "base/application.hpp"
|
#include "base/application.hpp"
|
||||||
@ -132,22 +131,11 @@ int ReplCommand::Run(const po::variables_map& vm, const std::vector<std::string>
|
|||||||
Expression *expr;
|
Expression *expr;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ConfigCompilerContext::GetInstance()->Reset();
|
|
||||||
|
|
||||||
lines[fileName] = line;
|
lines[fileName] = line;
|
||||||
|
|
||||||
expr = ConfigCompiler::CompileText(fileName, line);
|
expr = ConfigCompiler::CompileText(fileName, line);
|
||||||
|
|
||||||
bool has_errors = false;
|
if (expr) {
|
||||||
|
|
||||||
BOOST_FOREACH(const ConfigCompilerMessage& message, ConfigCompilerContext::GetInstance()->GetMessages()) {
|
|
||||||
if (message.Error)
|
|
||||||
has_errors = true;
|
|
||||||
|
|
||||||
std::cout << (message.Error ? "Error" : "Warning") << ": " << message.Text << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expr && !has_errors) {
|
|
||||||
Value result = expr->Evaluate(frame);
|
Value result = expr->Evaluate(frame);
|
||||||
std::cout << ConsoleColorTag(Console_ForegroundCyan);
|
std::cout << ConsoleColorTag(Console_ForegroundCyan);
|
||||||
if (!result.IsObject() || result.IsObjectType<Array>() || result.IsObjectType<Dictionary>())
|
if (!result.IsObject() || result.IsObjectType<Array>() || result.IsObjectType<Dictionary>())
|
||||||
|
@ -229,8 +229,6 @@ bool RepositoryUtility::AddObject(const String& name, const String& type, const
|
|||||||
change->Set("command", "add");
|
change->Set("command", "add");
|
||||||
change->Set("attrs", attrs);
|
change->Set("attrs", attrs);
|
||||||
|
|
||||||
ConfigCompilerContext::GetInstance()->Reset();
|
|
||||||
|
|
||||||
String fname, fragment;
|
String fname, fragment;
|
||||||
BOOST_FOREACH(boost::tie(fname, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) {
|
BOOST_FOREACH(boost::tie(fname, fragment), ConfigFragmentRegistry::GetInstance()->GetItems()) {
|
||||||
Expression *expression = ConfigCompiler::CompileText(fname, fragment);
|
Expression *expression = ConfigCompiler::CompileText(fname, fragment);
|
||||||
@ -258,25 +256,13 @@ bool RepositoryUtility::AddObject(const String& name, const String& type, const
|
|||||||
Object::Ptr object = dtype->Instantiate();
|
Object::Ptr object = dtype->Instantiate();
|
||||||
Deserialize(object, vattrs, false, FAConfig);
|
Deserialize(object, vattrs, false, FAConfig);
|
||||||
|
|
||||||
RepositoryTypeRuleUtilities utils;
|
try {
|
||||||
ctype->ValidateItem(name, object, DebugInfo(), &utils);
|
RepositoryTypeRuleUtilities utils;
|
||||||
|
ctype->ValidateItem(name, object, DebugInfo(), &utils);
|
||||||
int warnings = 0, errors = 0;
|
} catch (const ScriptError& ex) {
|
||||||
|
Log(LogCritical, "config", DiagnosticInformation(ex));
|
||||||
BOOST_FOREACH(const ConfigCompilerMessage& message, ConfigCompilerContext::GetInstance()->GetMessages()) {
|
|
||||||
String logmsg = String("Config ") + (message.Error ? "error" : "warning") + ": " + message.Text;
|
|
||||||
|
|
||||||
if (message.Error) {
|
|
||||||
Log(LogCritical, "config", logmsg);
|
|
||||||
errors++;
|
|
||||||
} else {
|
|
||||||
Log(LogWarning, "config", logmsg);
|
|
||||||
warnings++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errors > 0)
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CheckChangeExists(change)) {
|
if (CheckChangeExists(change)) {
|
||||||
|
@ -570,8 +570,8 @@ void CompatLogger::ValidateRotationMethod(const String& location, const CompatLo
|
|||||||
|
|
||||||
if (rotation_method != "HOURLY" && rotation_method != "DAILY" &&
|
if (rotation_method != "HOURLY" && rotation_method != "DAILY" &&
|
||||||
rotation_method != "WEEKLY" && rotation_method != "MONTHLY" && rotation_method != "NONE") {
|
rotation_method != "WEEKLY" && rotation_method != "MONTHLY" && rotation_method != "NONE") {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": Rotation method '" + rotation_method + "' is invalid.");
|
location + ": Rotation method '" + rotation_method + "' is invalid.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include "base/utility.hpp"
|
#include "base/utility.hpp"
|
||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
#include "base/dynamictype.hpp"
|
#include "base/dynamictype.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
@ -27,39 +27,6 @@
|
|||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
void ConfigCompilerContext::AddMessage(bool error, const String& message, const DebugInfo& di)
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
|
||||||
|
|
||||||
m_Messages.push_back(ConfigCompilerMessage(error, message, di));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ConfigCompilerMessage> ConfigCompilerContext::GetMessages(void) const
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
|
||||||
|
|
||||||
return m_Messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConfigCompilerContext::HasErrors(void) const
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
|
||||||
|
|
||||||
BOOST_FOREACH(const ConfigCompilerMessage& message, m_Messages) {
|
|
||||||
if (message.Error)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigCompilerContext::Reset(void)
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
|
||||||
|
|
||||||
m_Messages.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigCompilerContext *ConfigCompilerContext::GetInstance(void)
|
ConfigCompilerContext *ConfigCompilerContext::GetInstance(void)
|
||||||
{
|
{
|
||||||
return Singleton<ConfigCompilerContext>::GetInstance();
|
return Singleton<ConfigCompilerContext>::GetInstance();
|
||||||
|
@ -47,12 +47,6 @@ struct I2_CONFIG_API ConfigCompilerMessage
|
|||||||
class I2_CONFIG_API ConfigCompilerContext
|
class I2_CONFIG_API ConfigCompilerContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void AddMessage(bool error, const String& message, const DebugInfo& di = DebugInfo());
|
|
||||||
std::vector<ConfigCompilerMessage> GetMessages(void) const;
|
|
||||||
bool HasErrors(void) const;
|
|
||||||
|
|
||||||
void Reset(void);
|
|
||||||
|
|
||||||
void OpenObjectsFile(const String& filename);
|
void OpenObjectsFile(const String& filename);
|
||||||
void WriteObject(const Dictionary::Ptr& object);
|
void WriteObject(const Dictionary::Ptr& object);
|
||||||
void FinishObjectsFile(void);
|
void FinishObjectsFile(void);
|
||||||
@ -60,7 +54,6 @@ public:
|
|||||||
static ConfigCompilerContext *GetInstance(void);
|
static ConfigCompilerContext *GetInstance(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<ConfigCompilerMessage> m_Messages;
|
|
||||||
String m_ObjectsPath;
|
String m_ObjectsPath;
|
||||||
StdioStream::Ptr m_ObjectsFP;
|
StdioStream::Ptr m_ObjectsFP;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include "base/netstring.hpp"
|
#include "base/netstring.hpp"
|
||||||
#include "base/serializer.hpp"
|
#include "base/serializer.hpp"
|
||||||
#include "base/json.hpp"
|
#include "base/json.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
@ -163,16 +163,10 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
|
|||||||
|
|
||||||
DebugHint debugHints;
|
DebugHint debugHints;
|
||||||
|
|
||||||
try {
|
ScriptFrame frame(dobj);
|
||||||
ScriptFrame frame(dobj);
|
if (m_Scope)
|
||||||
if (m_Scope)
|
m_Scope->CopyTo(frame.Locals);
|
||||||
m_Scope->CopyTo(frame.Locals);
|
m_Expression->Evaluate(frame, &debugHints);
|
||||||
m_Expression->Evaluate(frame, &debugHints);
|
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (discard)
|
if (discard)
|
||||||
m_Expression.reset();
|
m_Expression.reset();
|
||||||
@ -222,18 +216,9 @@ DynamicObject::Ptr ConfigItem::Commit(bool discard)
|
|||||||
|
|
||||||
ConfigType::Ptr ctype = ConfigType::GetByName(GetType());
|
ConfigType::Ptr ctype = ConfigType::GetByName(GetType());
|
||||||
|
|
||||||
if (!ctype)
|
if (ctype)
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(false, "No validation type found for object '" + GetName() + "' of type '" + GetType() + "'");
|
|
||||||
else {
|
|
||||||
TypeRuleUtilities utils;
|
TypeRuleUtilities utils;
|
||||||
|
ctype->ValidateItem(GetName(), dobj, GetDebugInfo(), &utils);
|
||||||
try {
|
|
||||||
ctype->ValidateItem(GetName(), dobj, GetDebugInfo(), &utils);
|
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dobj->Register();
|
dobj->Register();
|
||||||
@ -287,7 +272,7 @@ ConfigItem::Ptr ConfigItem::GetObject(const String& type, const String& name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigItem::CommitNewItems(ParallelWorkQueue& upq)
|
bool ConfigItem::CommitNewItems(WorkQueue& upq)
|
||||||
{
|
{
|
||||||
typedef std::pair<ConfigItem::Ptr, bool> ItemPair;
|
typedef std::pair<ConfigItem::Ptr, bool> ItemPair;
|
||||||
std::vector<ItemPair> items;
|
std::vector<ItemPair> items;
|
||||||
@ -320,7 +305,7 @@ bool ConfigItem::CommitNewItems(ParallelWorkQueue& upq)
|
|||||||
|
|
||||||
upq.Join();
|
upq.Join();
|
||||||
|
|
||||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
if (upq.HasExceptions())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::vector<ConfigItem::Ptr> new_items;
|
std::vector<ConfigItem::Ptr> new_items;
|
||||||
@ -340,22 +325,18 @@ bool ConfigItem::CommitNewItems(ParallelWorkQueue& upq)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigItem::ValidateItems(void)
|
bool ConfigItem::CommitItems(void)
|
||||||
{
|
{
|
||||||
ParallelWorkQueue upq;
|
WorkQueue upq(25000, Application::GetConcurrency());
|
||||||
|
|
||||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Log(LogInformation, "ConfigItem", "Committing config items");
|
Log(LogInformation, "ConfigItem", "Committing config items");
|
||||||
|
|
||||||
if (!CommitNewItems(upq))
|
if (!CommitNewItems(upq)) {
|
||||||
|
upq.ReportExceptions("config");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ApplyRule::CheckMatches();
|
ApplyRule::CheckMatches();
|
||||||
ApplyRule::DiscardRules();
|
|
||||||
|
|
||||||
ConfigItem::DiscardItems();
|
|
||||||
ConfigType::DiscardTypes();
|
ConfigType::DiscardTypes();
|
||||||
|
|
||||||
/* log stats for external parsers */
|
/* log stats for external parsers */
|
||||||
@ -366,14 +347,11 @@ bool ConfigItem::ValidateItems(void)
|
|||||||
<< "Checked " << count << " " << type->GetName() << "(s).";
|
<< "Checked " << count << " " << type->GetName() << "(s).";
|
||||||
}
|
}
|
||||||
|
|
||||||
return !ConfigCompilerContext::GetInstance()->HasErrors();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigItem::ActivateItems(void)
|
bool ConfigItem::ActivateItems(void)
|
||||||
{
|
{
|
||||||
if (ConfigCompilerContext::GetInstance()->HasErrors())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* restore the previous program state */
|
/* restore the previous program state */
|
||||||
try {
|
try {
|
||||||
DynamicObject::RestoreObjects(Application::GetStatePath());
|
DynamicObject::RestoreObjects(Application::GetStatePath());
|
||||||
@ -384,7 +362,7 @@ bool ConfigItem::ActivateItems(void)
|
|||||||
|
|
||||||
Log(LogInformation, "ConfigItem", "Triggering Start signal for config items");
|
Log(LogInformation, "ConfigItem", "Triggering Start signal for config items");
|
||||||
|
|
||||||
ParallelWorkQueue upq;
|
WorkQueue upq(25000, Application::GetConcurrency());
|
||||||
|
|
||||||
BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
|
BOOST_FOREACH(const DynamicType::Ptr& type, DynamicType::GetTypes()) {
|
||||||
BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) {
|
BOOST_FOREACH(const DynamicObject::Ptr& object, type->GetObjects()) {
|
||||||
@ -414,13 +392,6 @@ bool ConfigItem::ActivateItems(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigItem::DiscardItems(void)
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_Mutex);
|
|
||||||
|
|
||||||
m_Items.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ConfigItem::Ptr> ConfigItem::GetItems(const String& type)
|
std::vector<ConfigItem::Ptr> ConfigItem::GetItems(const String& type)
|
||||||
{
|
{
|
||||||
std::vector<ConfigItem::Ptr> items;
|
std::vector<ConfigItem::Ptr> items;
|
||||||
|
@ -64,9 +64,8 @@ public:
|
|||||||
static ConfigItem::Ptr GetObject(const String& type,
|
static ConfigItem::Ptr GetObject(const String& type,
|
||||||
const String& name);
|
const String& name);
|
||||||
|
|
||||||
static bool ValidateItems(void);
|
static bool CommitItems(void);
|
||||||
static bool ActivateItems(void);
|
static bool ActivateItems(void);
|
||||||
static void DiscardItems(void);
|
|
||||||
|
|
||||||
static std::vector<ConfigItem::Ptr> GetItems(const String& type);
|
static std::vector<ConfigItem::Ptr> GetItems(const String& type);
|
||||||
|
|
||||||
@ -96,7 +95,7 @@ private:
|
|||||||
static ConfigItem::Ptr GetObjectUnlocked(const String& type,
|
static ConfigItem::Ptr GetObjectUnlocked(const String& type,
|
||||||
const String& name);
|
const String& name);
|
||||||
|
|
||||||
static bool CommitNewItems(ParallelWorkQueue& upq);
|
static bool CommitNewItems(WorkQueue& upq);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -136,14 +136,14 @@ void ConfigType::ValidateAttribute(const String& key, const Value& value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (overallResult == ValidationUnknownField)
|
if (overallResult == ValidationUnknownField)
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Unknown attribute: " + LocationToString(locations));
|
BOOST_THROW_EXCEPTION(ScriptError("Unknown attribute: " + LocationToString(locations)));
|
||||||
else if (overallResult == ValidationInvalidType) {
|
else if (overallResult == ValidationInvalidType) {
|
||||||
String message = "Invalid value: " + LocationToString(locations);
|
String message = "Invalid value: " + LocationToString(locations);
|
||||||
|
|
||||||
if (!hint.IsEmpty())
|
if (!hint.IsEmpty())
|
||||||
message += ": " + hint;
|
message += ": " + hint;
|
||||||
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, message);
|
BOOST_THROW_EXCEPTION(ScriptError(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!subRuleLists.empty() && value.IsObject() && !value.IsObjectType<Array>())
|
if (!subRuleLists.empty() && value.IsObject() && !value.IsObjectType<Array>())
|
||||||
@ -164,10 +164,8 @@ void ConfigType::ValidateObject(const Object::Ptr& object,
|
|||||||
|
|
||||||
Value value = VMOps::GetField(object, require);
|
Value value = VMOps::GetField(object, require);
|
||||||
|
|
||||||
if (value.IsEmpty() || (value.IsString() && static_cast<String>(value).IsEmpty())) {
|
if (value.IsEmpty() || (value.IsString() && static_cast<String>(value).IsEmpty()))
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true,
|
BOOST_THROW_EXCEPTION(ScriptError("Required attribute is missing: " + LocationToString(locations)));
|
||||||
"Required attribute is missing: " + LocationToString(locations));
|
|
||||||
}
|
|
||||||
|
|
||||||
locations.pop_back();
|
locations.pop_back();
|
||||||
}
|
}
|
||||||
@ -223,10 +221,8 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
|
|||||||
|
|
||||||
locations.push_back("Attribute '" + require + "'");
|
locations.push_back("Attribute '" + require + "'");
|
||||||
|
|
||||||
if (array->GetLength() < index) {
|
if (array->GetLength() < index)
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true,
|
BOOST_THROW_EXCEPTION(ScriptError("Required array index is missing: " + LocationToString(locations)));
|
||||||
"Required array index is missing: " + LocationToString(locations));
|
|
||||||
}
|
|
||||||
|
|
||||||
locations.pop_back();
|
locations.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include "base/json.hpp"
|
#include "base/json.hpp"
|
||||||
#include "base/object.hpp"
|
#include "base/object.hpp"
|
||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include "base/scriptglobal.hpp"
|
#include "base/scriptglobal.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/exception_ptr.hpp>
|
#include <boost/exception_ptr.hpp>
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "base/array.hpp"
|
#include "base/array.hpp"
|
||||||
#include "base/dictionary.hpp"
|
#include "base/dictionary.hpp"
|
||||||
#include "base/scriptfunction.hpp"
|
#include "base/scriptfunction.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include "base/scriptframe.hpp"
|
#include "base/scriptframe.hpp"
|
||||||
#include "base/convert.hpp"
|
#include "base/convert.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "base/dictionary.hpp"
|
#include "base/dictionary.hpp"
|
||||||
#include "base/scriptfunction.hpp"
|
#include "base/scriptfunction.hpp"
|
||||||
#include "base/scriptglobal.hpp"
|
#include "base/scriptglobal.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include "base/convert.hpp"
|
#include "base/convert.hpp"
|
||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
@ -424,7 +424,7 @@ void DbConnection::PrepareDatabase(void)
|
|||||||
void DbConnection::ValidateFailoverTimeout(const String& location, const DbConnection::Ptr& object)
|
void DbConnection::ValidateFailoverTimeout(const String& location, const DbConnection::Ptr& object)
|
||||||
{
|
{
|
||||||
if (object->GetFailoverTimeout() < 60) {
|
if (object->GetFailoverTimeout() < 60) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": Failover timeout minimum is 60s.");
|
location + ": Failover timeout minimum is 60s.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ void IdoMysqlConnection::ExceptionHandler(boost::exception_ptr exp)
|
|||||||
|
|
||||||
void IdoMysqlConnection::AssertOnWorkQueue(void)
|
void IdoMysqlConnection::AssertOnWorkQueue(void)
|
||||||
{
|
{
|
||||||
ASSERT(boost::this_thread::get_id() == m_QueryQueue.GetThreadId());
|
ASSERT(m_QueryQueue.IsWorkerThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdoMysqlConnection::Disconnect(void)
|
void IdoMysqlConnection::Disconnect(void)
|
||||||
|
@ -116,7 +116,7 @@ void IdoPgsqlConnection::ExceptionHandler(boost::exception_ptr exp)
|
|||||||
|
|
||||||
void IdoPgsqlConnection::AssertOnWorkQueue(void)
|
void IdoPgsqlConnection::AssertOnWorkQueue(void)
|
||||||
{
|
{
|
||||||
ASSERT(boost::this_thread::get_id() == m_QueryQueue.GetThreadId());
|
ASSERT(m_QueryQueue.IsWorkerThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdoPgsqlConnection::Disconnect(void)
|
void IdoPgsqlConnection::Disconnect(void)
|
||||||
|
@ -270,7 +270,7 @@ Endpoint::Ptr Checkable::GetCommandEndpoint(void) const
|
|||||||
void Checkable::ValidateCheckInterval(const String& location, const Checkable::Ptr& object)
|
void Checkable::ValidateCheckInterval(const String& location, const Checkable::Ptr& object)
|
||||||
{
|
{
|
||||||
if (object->GetCheckInterval() <= 0) {
|
if (object->GetCheckInterval() <= 0) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": check_interval must be greater than 0.");
|
location + ": check_interval must be greater than 0.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ void Command::SetModifiedAttributes(int flags, const MessageOrigin& origin)
|
|||||||
void Command::ValidateAttributes(const String& location, const Command::Ptr& object)
|
void Command::ValidateAttributes(const String& location, const Command::Ptr& object)
|
||||||
{
|
{
|
||||||
if (object->GetArguments() != Empty && !object->GetCommandLine().IsObjectType<Array>()) {
|
if (object->GetArguments() != Empty && !object->GetCommandLine().IsObjectType<Array>()) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": Attribute 'command' must be an array if the 'arguments' attribute is set.");
|
location + ": Attribute 'command' must be an array if the 'arguments' attribute is set.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/context.hpp"
|
#include "base/context.hpp"
|
||||||
#include "base/workqueue.hpp"
|
#include "base/workqueue.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
@ -150,12 +150,8 @@ void Dependency::EvaluateApplyRules(const Host::Ptr& host)
|
|||||||
if (rule.GetTargetType() != "Host")
|
if (rule.GetTargetType() != "Host")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
if (EvaluateApplyRule(host, rule))
|
||||||
if (EvaluateApplyRule(host, rule))
|
rule.AddMatch();
|
||||||
rule.AddMatch();
|
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,11 +163,7 @@ void Dependency::EvaluateApplyRules(const Service::Ptr& service)
|
|||||||
if (rule.GetTargetType() != "Service")
|
if (rule.GetTargetType() != "Service")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
if (EvaluateApplyRule(service, rule))
|
||||||
if (EvaluateApplyRule(service, rule))
|
rule.AddMatch();
|
||||||
rule.AddMatch();
|
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,12 +208,12 @@ void Dependency::ValidateFilters(const String& location, const Dependency::Ptr&
|
|||||||
int sfilter = FilterArrayToInt(object->GetStates(), 0);
|
int sfilter = FilterArrayToInt(object->GetStates(), 0);
|
||||||
|
|
||||||
if (object->GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
if (object->GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": State filter is invalid for host dependency.");
|
location + ": State filter is invalid for host dependency.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!object->GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
if (!object->GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": State filter is invalid for service dependency.");
|
location + ": State filter is invalid for service dependency.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "icinga/pluginutility.hpp"
|
#include "icinga/pluginutility.hpp"
|
||||||
#include "icinga/scheduleddowntime.hpp"
|
#include "icinga/scheduleddowntime.hpp"
|
||||||
#include "config/configcompilercontext.hpp"
|
#include "config/configcompilercontext.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
#include "base/convert.hpp"
|
#include "base/convert.hpp"
|
||||||
#include "base/utility.hpp"
|
#include "base/utility.hpp"
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/context.hpp"
|
#include "base/context.hpp"
|
||||||
#include "base/workqueue.hpp"
|
#include "base/workqueue.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
@ -150,12 +150,8 @@ void Notification::EvaluateApplyRules(const Host::Ptr& host)
|
|||||||
if (rule.GetTargetType() != "Host")
|
if (rule.GetTargetType() != "Host")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
if (EvaluateApplyRule(host, rule))
|
||||||
if (EvaluateApplyRule(host, rule))
|
rule.AddMatch();
|
||||||
rule.AddMatch();
|
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,11 +163,7 @@ void Notification::EvaluateApplyRules(const Service::Ptr& service)
|
|||||||
if (rule.GetTargetType() != "Service")
|
if (rule.GetTargetType() != "Service")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
if (EvaluateApplyRule(service, rule))
|
||||||
if (EvaluateApplyRule(service, rule))
|
rule.AddMatch();
|
||||||
rule.AddMatch();
|
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,13 +501,13 @@ void Notification::ValidateFilters(const String& location, const Notification::P
|
|||||||
int sfilter = FilterArrayToInt(object->GetStates(), 0);
|
int sfilter = FilterArrayToInt(object->GetStates(), 0);
|
||||||
|
|
||||||
if (object->GetServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
if (object->GetServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": State filter is invalid.");
|
location + ": State filter is invalid.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!object->GetServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
if (!object->GetServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": State filter is invalid.");
|
location + ": State filter is invalid.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int tfilter = FilterArrayToInt(object->GetTypes(), 0);
|
int tfilter = FilterArrayToInt(object->GetTypes(), 0);
|
||||||
@ -515,8 +515,8 @@ void Notification::ValidateFilters(const String& location, const Notification::P
|
|||||||
if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
|
if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
|
||||||
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
|
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
|
||||||
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0) {
|
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": Type filter is invalid.");
|
location + ": Type filter is invalid.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "base/dynamictype.hpp"
|
#include "base/dynamictype.hpp"
|
||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/context.hpp"
|
#include "base/context.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
@ -148,12 +148,8 @@ void ScheduledDowntime::EvaluateApplyRules(const Host::Ptr& host)
|
|||||||
if (rule.GetTargetType() != "Host")
|
if (rule.GetTargetType() != "Host")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
if (EvaluateApplyRule(host, rule))
|
||||||
if (EvaluateApplyRule(host, rule))
|
rule.AddMatch();
|
||||||
rule.AddMatch();
|
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,11 +161,7 @@ void ScheduledDowntime::EvaluateApplyRules(const Service::Ptr& service)
|
|||||||
if (rule.GetTargetType() != "Service")
|
if (rule.GetTargetType() != "Service")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
if (EvaluateApplyRule(service, rule))
|
||||||
if (EvaluateApplyRule(service, rule))
|
rule.AddMatch();
|
||||||
rule.AddMatch();
|
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/context.hpp"
|
#include "base/context.hpp"
|
||||||
#include "base/workqueue.hpp"
|
#include "base/workqueue.hpp"
|
||||||
#include "base/scripterror.hpp"
|
#include "base/exception.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
@ -133,11 +133,7 @@ void Service::EvaluateApplyRules(const Host::Ptr& host)
|
|||||||
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("Service")) {
|
BOOST_FOREACH(ApplyRule& rule, ApplyRule::GetRules("Service")) {
|
||||||
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
CONTEXT("Evaluating 'apply' rules for host '" + host->GetName() + "'");
|
||||||
|
|
||||||
try {
|
if (EvaluateApplyRule(host, rule))
|
||||||
if (EvaluateApplyRule(host, rule))
|
rule.AddMatch();
|
||||||
rule.AddMatch();
|
|
||||||
} catch (const ScriptError& ex) {
|
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), ex.GetDebugInfo());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,8 +106,8 @@ void User::ValidateFilters(const String& location, const Dictionary::Ptr& attrs)
|
|||||||
int sfilter = FilterArrayToInt(attrs->Get("states"), 0);
|
int sfilter = FilterArrayToInt(attrs->Get("states"), 0);
|
||||||
|
|
||||||
if ((sfilter & ~(StateFilterUp | StateFilterDown | StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
if ((sfilter & ~(StateFilterUp | StateFilterDown | StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": State filter is invalid.");
|
location + ": State filter is invalid.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int tfilter = FilterArrayToInt(attrs->Get("types"), 0);
|
int tfilter = FilterArrayToInt(attrs->Get("types"), 0);
|
||||||
@ -115,8 +115,8 @@ void User::ValidateFilters(const String& location, const Dictionary::Ptr& attrs)
|
|||||||
if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
|
if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
|
||||||
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
|
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
|
||||||
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0) {
|
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0) {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": Type filter is invalid.");
|
location + ": Type filter is invalid.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ void LivestatusListener::ValidateSocketType(const String& location, const Livest
|
|||||||
String socket_type = object->GetSocketType();
|
String socket_type = object->GetSocketType();
|
||||||
|
|
||||||
if (socket_type != "unix" && socket_type != "tcp") {
|
if (socket_type != "unix" && socket_type != "tcp") {
|
||||||
ConfigCompilerContext::GetInstance()->AddMessage(true, "Validation failed for " +
|
BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
|
||||||
location + ": Socket type '" + socket_type + "' is invalid.");
|
location + ": Socket type '" + socket_type + "' is invalid.", GetDebugInfo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user