Skip to content
Commits on Source (5)
# Icinga 2.x CHANGELOG
## 2.10.2 (2018-11-14)
### Bug
* [#6770](https://github.com/icinga/icinga2/issues/6770) (PR): Fix deadlock in GraphiteWriter
* [#6769](https://github.com/icinga/icinga2/issues/6769) (Cluster): Hanging TLS connections
* [#6759](https://github.com/icinga/icinga2/issues/6759) (Log, PR): Fix possible double free in StreamLogger::BindStream\(\)
* [#6753](https://github.com/icinga/icinga2/issues/6753): Icinga2.service state is reloading in systemd after safe-reload until systemd time-out
* [#6740](https://github.com/icinga/icinga2/issues/6740) (DB IDO, PR): DB IDO: Don't enqueue queries when the feature is paused \(HA\)
* [#6738](https://github.com/icinga/icinga2/issues/6738) (API, Cluster, PR): Ensure that API/JSON-RPC messages in the same session are processed and not stalled
* [#6736](https://github.com/icinga/icinga2/issues/6736) (Crash): Stability issues with Icinga 2.10.x
* [#6717](https://github.com/icinga/icinga2/issues/6717) (API, PR): Improve error handling for invalid child\_options for API downtime actions
* [#6712](https://github.com/icinga/icinga2/issues/6712) (API): Downtime name not returned when error occurs
* [#6711](https://github.com/icinga/icinga2/issues/6711) (API, Cluster): Slow API \(TLS-Handshake\)
* [#6709](https://github.com/icinga/icinga2/issues/6709) (PR): Fix the Icinga2 version check for versions with more than 5 characters
* [#6707](https://github.com/icinga/icinga2/issues/6707) (Compat, PR): Fix regression for wrong objects.cache path overwriting icinga2.debug file
* [#6705](https://github.com/icinga/icinga2/issues/6705) (CLI, Compat, Configuration): Crash "icinga2 object list" command with 2.10.1-1 on CentOS 7
* [#6703](https://github.com/icinga/icinga2/issues/6703): Check command 'icinga' breaks when vars.icinga\_min\_version is defined \(2.10.x\)
* [#6635](https://github.com/icinga/icinga2/issues/6635) (API): API TLS session connection closed after 2 requests
* [#5876](https://github.com/icinga/icinga2/issues/5876) (DB IDO): IDO Work queue on the inactive node growing when switching connection between redundant master servers
### Documentation
* [#6714](https://github.com/icinga/icinga2/issues/6714) (Documentation, PR): Docs: Add package related changes to the upgrading docs
### Support
* [#6773](https://github.com/icinga/icinga2/issues/6773) (Installation, Packages, PR): Initialize ICINGA2\_ERROR\_LOG inside the systemd environment
* [#6771](https://github.com/icinga/icinga2/issues/6771) (Tests, PR): Implement unit tests for Dictionary initializers
* [#6760](https://github.com/icinga/icinga2/issues/6760) (Packages, Tests, PR): armhf: Apply workaround for timer tests with std::bind callbacks
* [#6710](https://github.com/icinga/icinga2/issues/6710) (Packages): Crash when upgrading from 2.10.0 to 2.10.1 \(SELinux related\)
## 2.10.1 (2018-10-18)
### Bug
......
......@@ -26,7 +26,7 @@
Specify the release version.
```
VERSION=2.10.1
VERSION=2.10.2
```
Add your signing key to your Git configuration file, if not already there.
......
Version: 2.10.1
Version: 2.10.2
Revision: 1
icinga2 (2.10.2-1) unstable; urgency=medium
* Team upload.
* New upstream release.
* Drop 42_mips_boost_bind_workaround patch, applied upstream.
-- Bas Couwenberg <sebastic@debian.org> Mon, 19 Nov 2018 18:20:51 +0100
icinga2 (2.10.1-3) unstable; urgency=medium
* Team upload.
......
Description: Working around MIPS* build problems with boost::bind
Bug: https://github.com/Icinga/icinga2/issues/4824
Reviewed-by: Markus Frosch <lazyfrosch@debian.org>
Last-Update: 2016-12-16
---
commit 5985134bf3650d3cb0dac5531db5e2ffc95ce681
Author: Markus Frosch <markus.frosch@icinga.com>
Date: Fri Dec 16 18:26:43 2016 +0100
test/base-timer: Workaround boost::bind problem on mips* architectures
refs #13403
--- a/test/base-timer.cpp
+++ b/test/base-timer.cpp
@@ -39,16 +39,17 @@ BOOST_AUTO_TEST_CASE(interval)
BOOST_CHECK(timer->GetInterval() == 1.5);
}
-static void Callback(int *counter)
+int counter = 0;
+
+static void Callback(const Timer::Ptr&)
{
- (*counter)++;
+ counter++;
}
BOOST_AUTO_TEST_CASE(invoke)
{
- int counter;
Timer::Ptr timer = new Timer();
- timer->OnTimerExpired.connect(std::bind(&Callback, &counter));
+ timer->OnTimerExpired.connect(&Callback);
timer->SetInterval(1);
counter = 0;
@@ -61,9 +62,8 @@ BOOST_AUTO_TEST_CASE(invoke)
BOOST_AUTO_TEST_CASE(scope)
{
- int counter;
Timer::Ptr timer = new Timer();
- timer->OnTimerExpired.connect(std::bind(&Callback, &counter));
+ timer->OnTimerExpired.connect(&Callback);
timer->SetInterval(1);
counter = 0;
21_config_changes
42_mips_boost_bind_workaround
postgres-checkcommand.patch
......@@ -94,7 +94,7 @@ installation, configuration and integration.
### Dashing Dashboard <a id="addons-visualization-dashing-dashboard"></a>
The [Icinga 2 dashboard](https://github.com/dnsmichi/dashing-icinga2) is built
on top of Dashing and uses the [REST API](#icinga2-api) to visualize what's going
on top of Dashing and uses the [REST API](12-icinga2-api.md#icinga2-api) to visualize what's going
on with your monitoring. It combines several popular widgets and provides development
instructions for your own implementation.
......
......@@ -106,6 +106,22 @@ For example the following started to give a fatal error in 2.10:
```critical/config: Error: Zone 'XXX' can not have a global zone as parent.```
### Package Changes <a id="upgrading-to-2-10-package-changes"></a>
Debian/Ubuntu drops the `libicinga2` package. `apt-get upgrade icinga2`
won't remove such packages leaving the upgrade in an unsatisfied state.
Please use `apt-get full-upgrade` or `apt-get dist-upgrade` instead, as explained [here](https://github.com/Icinga/icinga2/issues/6695#issuecomment-430585915).
On RHEL/CentOS/Fedora, `icinga2-libs` has been obsoleted. Unfortunately yum's dependency
resolver doesn't allow to install older versions than 2.10 then. Please
read [here](https://github.com/Icinga/icinga-packaging/issues/114#issuecomment-429264827)
for details.
RPM packages dropped the [Classic UI](16-upgrading-icinga-2.md#upgrading-to-2-8-removed-classicui-config-package)
package in v2.8, Debian/Ubuntu packages were forgotten. This is now the case with this
release. Icinga 1.x is EOL by the end of 2018, plan your migration to [Icinga Web 2](https://icinga.com/docs/icingaweb2/latest/).
## Upgrading to v2.9 <a id="upgrading-to-2-9"></a>
### Deprecation and Removal Notes <a id="upgrading-to-2-9-deprecation-removal-notes"></a>
......
......@@ -4,6 +4,7 @@ After=syslog.target network-online.target postgresql.service mariadb.service car
[Service]
Type=notify
Environment="ICINGA2_ERROR_LOG=@ICINGA2_LOGDIR@/error.log"
EnvironmentFile=@ICINGA2_SYSCONFIGFILE@
ExecStartPre=@CMAKE_INSTALL_PREFIX@/lib/icinga2/prepare-dirs @ICINGA2_SYSCONFIGFILE@
ExecStart=@CMAKE_INSTALL_FULL_SBINDIR@/icinga2 daemon --close-stdio -e ${ICINGA2_ERROR_LOG}
......
......@@ -91,16 +91,6 @@ bool Stream::WaitForData(int timeout)
return IsDataAvailable() || IsEof();
}
void Stream::SetCorked(bool corked)
{
m_Corked = corked;
}
bool Stream::IsCorked() const
{
return m_Corked;
}
static void StreamDummyCallback()
{ }
......
......@@ -127,9 +127,6 @@ public:
bool WaitForData();
bool WaitForData(int timeout);
virtual void SetCorked(bool corked);
bool IsCorked() const;
virtual bool SupportsWaiting() const;
virtual bool IsDataAvailable() const;
......@@ -146,8 +143,6 @@ private:
boost::mutex m_Mutex;
boost::condition_variable m_CV;
bool m_Corked{false};
};
}
......
......@@ -47,7 +47,7 @@ StreamLogger::~StreamLogger()
if (m_FlushLogTimer)
m_FlushLogTimer->Stop();
if (m_OwnsStream)
if (m_Stream && m_OwnsStream)
delete m_Stream;
}
......@@ -66,7 +66,7 @@ void StreamLogger::BindStream(std::ostream *stream, bool ownsStream)
{
ObjectLock olock(this);
if (m_OwnsStream)
if (m_Stream && m_OwnsStream)
delete m_Stream;
m_Stream = stream;
......
......@@ -153,15 +153,11 @@ void TlsStream::OnEvent(int revents)
char buffer[64 * 1024];
if (m_CurrentAction == TlsActionNone) {
bool corked = IsCorked();
if (!corked && (revents & (POLLIN | POLLERR | POLLHUP)))
if (revents & (POLLIN | POLLERR | POLLHUP))
m_CurrentAction = TlsActionRead;
else if (m_SendQ->GetAvailableBytes() > 0 && (revents & POLLOUT))
m_CurrentAction = TlsActionWrite;
else {
if (corked)
ChangeEvents(0);
else
ChangeEvents(POLLIN);
return;
......@@ -289,7 +285,7 @@ void TlsStream::OnEvent(int revents)
lock.unlock();
while (!IsCorked() && m_RecvQ->IsDataAvailable() && IsHandlingEvents())
while (m_RecvQ->IsDataAvailable() && IsHandlingEvents())
SignalDataAvailable();
}
......@@ -428,18 +424,6 @@ bool TlsStream::IsDataAvailable() const
return m_RecvQ->GetAvailableBytes() > 0;
}
void TlsStream::SetCorked(bool corked)
{
Stream::SetCorked(corked);
boost::mutex::scoped_lock lock(m_Mutex);
if (corked)
m_CurrentAction = TlsActionNone;
else
ChangeEvents(POLLIN | POLLOUT);
}
Socket::Ptr TlsStream::GetSocket() const
{
return m_Socket;
......
......@@ -70,8 +70,6 @@ public:
bool SupportsWaiting() const override;
bool IsDataAvailable() const override;
void SetCorked(bool corked) override;
bool IsVerifyOK() const;
String GetVerifyError() const;
......
......@@ -559,7 +559,8 @@ void StatusDataWriter::UpdateObjectsCache()
{
CONTEXT("Writing objects.cache file");
String objectsPath = Configuration::ObjectsPath;
/* Use the compat path here from the .ti generated class. */
String objectsPath = GetObjectsPath();
std::fstream objectfp;
String tempObjectsPath = Utility::CreateTempFile(objectsPath + ".XXXXXX", 0644, objectfp);
......
......@@ -162,6 +162,9 @@ void IdoMysqlConnection::TxTimerHandler()
void IdoMysqlConnection::NewTransaction()
{
if (IsPaused())
return;
#ifdef I2_DEBUG /* I2_DEBUG */
Log(LogDebug, "IdoMysqlConnection")
<< "Scheduling new transaction and finishing async queries.";
......@@ -715,6 +718,9 @@ void IdoMysqlConnection::DiscardRows(const IdoMysqlResult& result)
void IdoMysqlConnection::ActivateObject(const DbObject::Ptr& dbobj)
{
if (IsPaused())
return;
#ifdef I2_DEBUG /* I2_DEBUG */
Log(LogDebug, "IdoMysqlConnection")
<< "Scheduling object activation task for '" << dbobj->GetName1() << "!" << dbobj->GetName2() << "'.";
......@@ -727,6 +733,9 @@ void IdoMysqlConnection::InternalActivateObject(const DbObject::Ptr& dbobj)
{
AssertOnWorkQueue();
if (IsPaused())
return;
if (!GetConnected())
return;
......@@ -754,6 +763,9 @@ void IdoMysqlConnection::InternalActivateObject(const DbObject::Ptr& dbobj)
void IdoMysqlConnection::DeactivateObject(const DbObject::Ptr& dbobj)
{
if (IsPaused())
return;
#ifdef I2_DEBUG /* I2_DEBUG */
Log(LogDebug, "IdoMysqlConnection")
<< "Scheduling object deactivation task for '" << dbobj->GetName1() << "!" << dbobj->GetName2() << "'.";
......@@ -766,6 +778,9 @@ void IdoMysqlConnection::InternalDeactivateObject(const DbObject::Ptr& dbobj)
{
AssertOnWorkQueue();
if (IsPaused())
return;
if (!GetConnected())
return;
......@@ -855,6 +870,9 @@ bool IdoMysqlConnection::FieldToEscapedString(const String& key, const Value& va
void IdoMysqlConnection::ExecuteQuery(const DbQuery& query)
{
if (IsPaused())
return;
ASSERT(query.Category != DbCatInvalid);
#ifdef I2_DEBUG /* I2_DEBUG */
......@@ -867,6 +885,9 @@ void IdoMysqlConnection::ExecuteQuery(const DbQuery& query)
void IdoMysqlConnection::ExecuteMultipleQueries(const std::vector<DbQuery>& queries)
{
if (IsPaused())
return;
if (queries.empty())
return;
......@@ -914,6 +935,9 @@ void IdoMysqlConnection::InternalExecuteMultipleQueries(const std::vector<DbQuer
{
AssertOnWorkQueue();
if (IsPaused())
return;
if (!GetConnected())
return;
......@@ -942,6 +966,9 @@ void IdoMysqlConnection::InternalExecuteQuery(const DbQuery& query, int typeOver
{
AssertOnWorkQueue();
if (IsPaused())
return;
if (!GetConnected())
return;
......@@ -1129,6 +1156,9 @@ void IdoMysqlConnection::FinishExecuteQuery(const DbQuery& query, int type, bool
void IdoMysqlConnection::CleanUpExecuteQuery(const String& table, const String& time_column, double max_age)
{
if (IsPaused())
return;
#ifdef I2_DEBUG /* I2_DEBUG */
Log(LogDebug, "IdoMysqlConnection")
<< "Rescheduling cleanup query for table '" << table << "' and column '"
......@@ -1142,6 +1172,9 @@ void IdoMysqlConnection::InternalCleanUpExecuteQuery(const String& table, const
{
AssertOnWorkQueue();
if (IsPaused())
return;
if (!GetConnected())
return;
......
......@@ -163,6 +163,9 @@ void IdoPgsqlConnection::TxTimerHandler()
void IdoPgsqlConnection::NewTransaction()
{
if (IsPaused())
return;
m_QueryQueue.Enqueue(std::bind(&IdoPgsqlConnection::InternalNewTransaction, this), PriorityHigh, true);
}
......@@ -569,6 +572,9 @@ Dictionary::Ptr IdoPgsqlConnection::FetchRow(const IdoPgsqlResult& result, int r
void IdoPgsqlConnection::ActivateObject(const DbObject::Ptr& dbobj)
{
if (IsPaused())
return;
m_QueryQueue.Enqueue(std::bind(&IdoPgsqlConnection::InternalActivateObject, this, dbobj), PriorityLow);
}
......@@ -603,6 +609,9 @@ void IdoPgsqlConnection::InternalActivateObject(const DbObject::Ptr& dbobj)
void IdoPgsqlConnection::DeactivateObject(const DbObject::Ptr& dbobj)
{
if (IsPaused())
return;
m_QueryQueue.Enqueue(std::bind(&IdoPgsqlConnection::InternalDeactivateObject, this, dbobj), PriorityLow);
}
......@@ -699,6 +708,9 @@ bool IdoPgsqlConnection::FieldToEscapedString(const String& key, const Value& va
void IdoPgsqlConnection::ExecuteQuery(const DbQuery& query)
{
if (IsPaused())
return;
ASSERT(query.Category != DbCatInvalid);
m_QueryQueue.Enqueue(std::bind(&IdoPgsqlConnection::InternalExecuteQuery, this, query, -1), query.Priority, true);
......@@ -706,6 +718,9 @@ void IdoPgsqlConnection::ExecuteQuery(const DbQuery& query)
void IdoPgsqlConnection::ExecuteMultipleQueries(const std::vector<DbQuery>& queries)
{
if (IsPaused())
return;
if (queries.empty())
return;
......@@ -748,6 +763,9 @@ void IdoPgsqlConnection::InternalExecuteMultipleQueries(const std::vector<DbQuer
{
AssertOnWorkQueue();
if (IsPaused())
return;
if (!GetConnected())
return;
......@@ -769,6 +787,9 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, int typeOver
{
AssertOnWorkQueue();
if (IsPaused())
return;
if (!GetConnected())
return;
......@@ -933,6 +954,9 @@ void IdoPgsqlConnection::InternalExecuteQuery(const DbQuery& query, int typeOver
void IdoPgsqlConnection::CleanUpExecuteQuery(const String& table, const String& time_column, double max_age)
{
if (IsPaused())
return;
m_QueryQueue.Enqueue(std::bind(&IdoPgsqlConnection::InternalCleanUpExecuteQuery, this, table, time_column, max_age), PriorityLow, true);
}
......
......@@ -355,6 +355,15 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
double startTime = HttpUtility::GetLastParameter(params, "start_time");
double endTime = HttpUtility::GetLastParameter(params, "end_time");
DowntimeChildOptions childOptions = DowntimeNoChildren;
if (params->Contains("child_options")) {
try {
childOptions = Downtime::ChildOptionsFromValue(HttpUtility::GetLastParameter(params, "child_options"));
} catch (const std::exception&) {
return ApiActions::CreateResult(400, "Option 'child_options' provided an invalid value.");
}
}
String downtimeName = Downtime::AddDowntime(checkable, author, comment, startTime, endTime,
fixed, triggerName, duration);
......@@ -366,10 +375,6 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
});
/* Schedule downtime for all child objects. */
DowntimeChildOptions childOptions = DowntimeNoChildren;
if (params->Contains("child_options"))
childOptions = Downtime::ChildOptionsFromValue(HttpUtility::GetLastParameter(params, "child_options"));
if (childOptions != DowntimeNoChildren) {
/* 'DowntimeTriggeredChildren' schedules child downtimes triggered by the parent downtime.
* 'DowntimeNonTriggeredChildren' schedules non-triggered downtimes for all children.
......
......@@ -174,9 +174,13 @@ void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
cr->SetState(ServiceWarning);
}
/* Return an error if the version is less than specified (optional). */
String parsedAppVersion = appVersion.SubStr(1,5);
/* Extract the version number of the running Icinga2 instance.
* We assume that appVersion will allways be something like 'v2.10.1-8-gaebe6da' and we want to extract '2.10.1'.
*/
int endOfVersionNumber = appVersion.FindFirstOf("-") - 1;
String parsedAppVersion = appVersion.SubStr(1, endOfVersionNumber);
/* Return an error if the version is less than specified (optional). */
if (missingIcingaMinVersion.IsEmpty() && !icingaMinVersion.IsEmpty() && Utility::CompareVersion(icingaMinVersion, parsedAppVersion) < 0) {
output += "; Minimum version " + icingaMinVersion + " is not installed.";
cr->SetState(ServiceCritical);
......
......@@ -49,15 +49,6 @@ void ElasticsearchWriter::OnConfigLoaded()
ObjectImpl<ElasticsearchWriter>::OnConfigLoaded();
m_WorkQueue.SetName("ElasticsearchWriter, " + GetName());
if (!GetEnableHa()) {
Log(LogDebug, "ElasticsearchWriter")
<< "HA functionality disabled. Won't pause connection: " << GetName();
SetHAMode(HARunEverywhere);
} else {
SetHAMode(HARunOnce);
}
}
void ElasticsearchWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata)
......