summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'net-analyzer')
-rw-r--r--net-analyzer/icinga2/Manifest1
-rw-r--r--net-analyzer/icinga2/files/icinga2-2.12.1-boost-1.74.0.patch436
-rw-r--r--net-analyzer/icinga2/icinga2-2.12.1.ebuild149
-rw-r--r--net-analyzer/icinga2/metadata.xml1
4 files changed, 587 insertions, 0 deletions
diff --git a/net-analyzer/icinga2/Manifest b/net-analyzer/icinga2/Manifest
index bff12455281e..2a6c58ace85f 100644
--- a/net-analyzer/icinga2/Manifest
+++ b/net-analyzer/icinga2/Manifest
@@ -1,3 +1,4 @@
DIST icinga2-2.11.5.tar.gz 7478038 BLAKE2B 309d090e9dab5fb79b411ee75bdcdc3351b559a434543937b3486bc0d45a25fc320609985e4130c2cca83972e4be15180f85bc4c78851fcecbc96ae523ca6bcd SHA512 22b0902818ee840c5c50da3768d6fc6dadf574d8fb5884eb45a2184b9e516888caa2e09ece4f8880139fb0931f131786002f494de702925a6f458968c3cee144
DIST icinga2-2.11.6.tar.gz 7480970 BLAKE2B d247a4c0272227e0dfa2df46f91d84c7630c56df8d77d7de30aea715509b68fddbe74ef58c9b50acb4965e7108c3f9c23cf4e9c0f1a572763c34dd87cfaae1ec SHA512 e455d10612721ef6090256618c5a87e2f06e6284c2b2d137b85058bb5cdc30f3524fbcab5559acbe891e37d90f862c1b117115451bb3b59b8a2f67bb9d027e6e
DIST icinga2-2.12.0.tar.gz 7530104 BLAKE2B 6f4a37d638449596d163add4ee070d24c1eb5f483e32f6c666454353578e6399a04cda949cb51b135516be7b437196e5beeff0e5e24a7bc26b855de87e24a797 SHA512 2a0ead159cfd71ebb662b909d8c4a64bdf13235b14d37b67057034da4fbf8764167b175e20f635989a98faafabb5da4f71321a4f8592172bed5cbb3ee557b276
+DIST icinga2-2.12.1.tar.gz 7532104 BLAKE2B addb3bb6f81cb41e1ec23e989d6151af6f39fdded5a76a791806114cc2ba46c786b5d6674e9e0e86eb701cb5132f766cdf3cbdfbbcc0f9263db3a7ba844705c6 SHA512 8c266db67fb7aa27dc86e9dc28fa0e1ff7b11260ed529d3963c5cf25a5230fc9f02d7d44076948fbde6e39e2cb02f2d99c2c5b72396154baf95aaa5eba461529
diff --git a/net-analyzer/icinga2/files/icinga2-2.12.1-boost-1.74.0.patch b/net-analyzer/icinga2/files/icinga2-2.12.1-boost-1.74.0.patch
new file mode 100644
index 000000000000..e6ad4807993a
--- /dev/null
+++ b/net-analyzer/icinga2/files/icinga2-2.12.1-boost-1.74.0.patch
@@ -0,0 +1,436 @@
+From c30bae2994f1e5f33f6da51eb96d423e9bf0f75c Mon Sep 17 00:00:00 2001
+From: Louis Sautier <sautier.louis@gmail.com>
+Date: Thu, 20 Aug 2020 18:25:48 +0200
+Subject: [PATCH] =?UTF-8?q?Fix=20=E2=80=98fs::copy=5Foption=E2=80=99=20has?=
+ =?UTF-8?q?=20not=20been=20declared=20with=20boost=201.74.0?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It was deprecated in
+https://github.com/boostorg/filesystem/commit/f199152b7df036ff1606c85e4ea1b28edfeda6cc
+---
+ lib/base/utility.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp
+index 1add7616c6..d8e6f20b0c 100644
+--- a/lib/base/utility.cpp
++++ b/lib/base/utility.cpp
+@@ -725,7 +725,11 @@ void Utility::CopyFile(const String& source, const String& target)
+ {
+ namespace fs = boost::filesystem;
+
++#if BOOST_VERSION >= 107400
++ fs::copy_file(fs::path(source.Begin(), source.End()), fs::path(target.Begin(), target.End()), fs::copy_options::overwrite_existing);
++#else /* BOOST_VERSION */
+ fs::copy_file(fs::path(source.Begin(), source.End()), fs::path(target.Begin(), target.End()), fs::copy_option::overwrite_if_exists);
++#endif /* BOOST_VERSION */
+ }
+
+ /*
+From 45dd71e0f9a93369e08d6cb26f97940f9c9594aa Mon Sep 17 00:00:00 2001
+From: "Alexander A. Klimov" <alexander.klimov@icinga.com>
+Date: Wed, 26 Aug 2020 13:56:26 +0200
+Subject: [PATCH] Introduce HttpUtility::Set()
+
+refs #8185
+---
+ lib/cli/consolecommand.cpp | 9 ++++---
+ lib/perfdata/elasticsearchwriter.cpp | 13 ++++-----
+ lib/perfdata/influxdbwriter.cpp | 7 ++---
+ lib/remote/configfileshandler.cpp | 4 +--
+ lib/remote/eventshandler.cpp | 2 +-
+ lib/remote/httpserverconnection.cpp | 40 ++++++++++++++--------------
+ lib/remote/httputility.cpp | 4 +--
+ lib/remote/httputility.hpp | 28 +++++++++++++++++++
+ lib/remote/infohandler.cpp | 6 ++---
+ plugins/check_nscp_api.cpp | 9 ++++---
+ 10 files changed, 77 insertions(+), 45 deletions(-)
+
+diff --git a/lib/cli/consolecommand.cpp b/lib/cli/consolecommand.cpp
+index 41b6590e4c..42c5c63133 100644
+--- a/lib/cli/consolecommand.cpp
++++ b/lib/cli/consolecommand.cpp
+@@ -3,6 +3,7 @@
+ #include "cli/consolecommand.hpp"
+ #include "config/configcompiler.hpp"
+ #include "remote/consolehandler.hpp"
++#include "remote/httputility.hpp"
+ #include "remote/url.hpp"
+ #include "base/configwriter.hpp"
+ #include "base/serializer.hpp"
+@@ -580,11 +581,11 @@ Dictionary::Ptr ConsoleCommand::SendRequest()
+
+ http::request<http::string_body> request(http::verb::post, std::string(l_Url->Format(false)), 10);
+
+- request.set(http::field::user_agent, "Icinga/DebugConsole/" + Application::GetAppVersion());
+- request.set(http::field::host, l_Url->GetHost() + ":" + l_Url->GetPort());
++ HttpUtility::Set(request, http::field::user_agent, "Icinga/DebugConsole/" + Application::GetAppVersion());
++ HttpUtility::Set(request, http::field::host, l_Url->GetHost() + ":" + l_Url->GetPort());
+
+- request.set(http::field::accept, "application/json");
+- request.set(http::field::authorization, "Basic " + Base64::Encode(l_Url->GetUsername() + ":" + l_Url->GetPassword()));
++ HttpUtility::Set(request, http::field::accept, "application/json");
++ HttpUtility::Set(request, http::field::authorization, "Basic " + Base64::Encode(l_Url->GetUsername() + ":" + l_Url->GetPassword()));
+
+ try {
+ http::write(*l_TlsStream, request);
+diff --git a/lib/perfdata/elasticsearchwriter.cpp b/lib/perfdata/elasticsearchwriter.cpp
+index 6870198e45..3764bf536b 100644
+--- a/lib/perfdata/elasticsearchwriter.cpp
++++ b/lib/perfdata/elasticsearchwriter.cpp
+@@ -2,6 +2,7 @@
+
+ #include "perfdata/elasticsearchwriter.hpp"
+ #include "perfdata/elasticsearchwriter-ti.cpp"
++#include "remote/httputility.hpp"
+ #include "remote/url.hpp"
+ #include "icinga/compatutility.hpp"
+ #include "icinga/service.hpp"
+@@ -474,27 +475,27 @@ void ElasticsearchWriter::SendRequest(const String& body)
+
+ http::request<http::string_body> request (http::verb::post, std::string(url->Format(true)), 10);
+
+- request.set(http::field::user_agent, "Icinga/" + Application::GetAppVersion());
+- request.set(http::field::host, url->GetHost() + ":" + url->GetPort());
++ HttpUtility::Set(request, http::field::user_agent, "Icinga/" + Application::GetAppVersion());
++ HttpUtility::Set(request, http::field::host, url->GetHost() + ":" + url->GetPort());
+
+ /* Specify required headers by Elasticsearch. */
+- request.set(http::field::accept, "application/json");
++ HttpUtility::Set(request, http::field::accept, "application/json");
+
+ /* Use application/x-ndjson for bulk streams. While ES
+ * is able to handle application/json, the newline separator
+ * causes problems with Logstash (#6609).
+ */
+- request.set(http::field::content_type, "application/x-ndjson");
++ HttpUtility::Set(request, http::field::content_type, "application/x-ndjson");
+
+ /* Send authentication if configured. */
+ String username = GetUsername();
+ String password = GetPassword();
+
+ if (!username.IsEmpty() && !password.IsEmpty())
+- request.set(http::field::authorization, "Basic " + Base64::Encode(username + ":" + password));
++ HttpUtility::Set(request, http::field::authorization, "Basic " + Base64::Encode(username + ":" + password));
+
+ request.body() = body;
+- request.set(http::field::content_length, request.body().size());
++ HttpUtility::Set(request, http::field::content_length, request.body().size());
+
+ /* Don't log the request body to debug log, this is already done above. */
+ Log(LogDebug, "ElasticsearchWriter")
+diff --git a/lib/perfdata/influxdbwriter.cpp b/lib/perfdata/influxdbwriter.cpp
+index 4692b8b5df..0ddd582447 100644
+--- a/lib/perfdata/influxdbwriter.cpp
++++ b/lib/perfdata/influxdbwriter.cpp
+@@ -2,6 +2,7 @@
+
+ #include "perfdata/influxdbwriter.hpp"
+ #include "perfdata/influxdbwriter-ti.cpp"
++#include "remote/httputility.hpp"
+ #include "remote/url.hpp"
+ #include "icinga/service.hpp"
+ #include "icinga/macroprocessor.hpp"
+@@ -501,11 +502,11 @@ void InfluxdbWriter::Flush()
+
+ http::request<http::string_body> request (http::verb::post, std::string(url->Format(true)), 10);
+
+- request.set(http::field::user_agent, "Icinga/" + Application::GetAppVersion());
+- request.set(http::field::host, url->GetHost() + ":" + url->GetPort());
++ HttpUtility::Set(request, http::field::user_agent, "Icinga/" + Application::GetAppVersion());
++ HttpUtility::Set(request, http::field::host, url->GetHost() + ":" + url->GetPort());
+
+ request.body() = body;
+- request.set(http::field::content_length, request.body().size());
++ HttpUtility::Set(request, http::field::content_length, request.body().size());
+
+ try {
+ if (stream.first) {
+diff --git a/lib/remote/configfileshandler.cpp b/lib/remote/configfileshandler.cpp
+index d714f4d864..5c2bfdb405 100644
+--- a/lib/remote/configfileshandler.cpp
++++ b/lib/remote/configfileshandler.cpp
+@@ -82,9 +82,9 @@ bool ConfigFilesHandler::HandleRequest(
+
+ String content((std::istreambuf_iterator<char>(fp)), std::istreambuf_iterator<char>());
+ response.result(http::status::ok);
+- response.set(http::field::content_type, "application/octet-stream");
++ HttpUtility::Set(response, http::field::content_type, "application/octet-stream");
+ response.body() = content;
+- response.set(http::field::content_length, response.body().size());
++ HttpUtility::Set(response, http::field::content_length, response.body().size());
+ } catch (const std::exception& ex) {
+ HttpUtility::SendJsonError(response, params, 500, "Could not read file.",
+ DiagnosticInformation(ex));
+diff --git a/lib/remote/eventshandler.cpp b/lib/remote/eventshandler.cpp
+index e92b14a2d4..e41b4711c6 100644
+--- a/lib/remote/eventshandler.cpp
++++ b/lib/remote/eventshandler.cpp
+@@ -100,7 +100,7 @@ bool EventsHandler::HandleRequest(
+ server.StartStreaming();
+
+ response.result(http::status::ok);
+- response.set(http::field::content_type, "application/json");
++ HttpUtility::Set(response, http::field::content_type, "application/json");
+
+ IoBoundWorkSlot dontLockTheIoThread (yc);
+
+diff --git a/lib/remote/httpserverconnection.cpp b/lib/remote/httpserverconnection.cpp
+index d4eac7d074..688392c821 100644
+--- a/lib/remote/httpserverconnection.cpp
++++ b/lib/remote/httpserverconnection.cpp
+@@ -184,12 +184,12 @@ bool EnsureValidHeaders(
+ { "status", String("Bad Request: ") + errorMsg }
+ }));
+ } else {
+- response.set(http::field::content_type, "text/html");
++ HttpUtility::Set(response, http::field::content_type, "text/html");
+ response.body() = String("<h1>Bad Request</h1><p><pre>") + errorMsg + "</pre></p>";
+- response.set(http::field::content_length, response.body().size());
++ HttpUtility::Set(response, http::field::content_length, response.body().size());
+ }
+
+- response.set(http::field::connection, "close");
++ HttpUtility::Set(response, http::field::connection, "close");
+
+ boost::system::error_code ec;
+
+@@ -247,20 +247,20 @@ bool HandleAccessControl(
+ auto& origin (request[http::field::origin]);
+
+ if (allowedOrigins.find(origin.to_string()) != allowedOrigins.end()) {
+- response.set(http::field::access_control_allow_origin, origin);
++ HttpUtility::Set(response, http::field::access_control_allow_origin, origin);
+ }
+
+ allowOriginHeader.Done();
+
+- response.set(http::field::access_control_allow_credentials, "true");
++ HttpUtility::Set(response, http::field::access_control_allow_credentials, "true");
+
+ if (request.method() == http::verb::options && !request[http::field::access_control_request_method].empty()) {
+ response.result(http::status::ok);
+- response.set(http::field::access_control_allow_methods, "GET, POST, PUT, DELETE");
+- response.set(http::field::access_control_allow_headers, "Authorization, X-HTTP-Method-Override");
++ HttpUtility::Set(response, http::field::access_control_allow_methods, "GET, POST, PUT, DELETE");
++ HttpUtility::Set(response, http::field::access_control_allow_headers, "Authorization, X-HTTP-Method-Override");
+ response.body() = "Preflight OK";
+- response.set(http::field::content_length, response.body().size());
+- response.set(http::field::connection, "close");
++ HttpUtility::Set(response, http::field::content_length, response.body().size());
++ HttpUtility::Set(response, http::field::connection, "close");
+
+ boost::system::error_code ec;
+
+@@ -288,10 +288,10 @@ bool EnsureAcceptHeader(
+
+ if (request.method() != http::verb::get && request[http::field::accept] != "application/json") {
+ response.result(http::status::bad_request);
+- response.set(http::field::content_type, "text/html");
++ HttpUtility::Set(response, http::field::content_type, "text/html");
+ response.body() = "<h1>Accept header is missing or not set to 'application/json'.</h1>";
+- response.set(http::field::content_length, response.body().size());
+- response.set(http::field::connection, "close");
++ HttpUtility::Set(response, http::field::content_length, response.body().size());
++ HttpUtility::Set(response, http::field::connection, "close");
+
+ boost::system::error_code ec;
+
+@@ -320,8 +320,8 @@ bool EnsureAuthenticatedUser(
+ << "Unauthorized request: " << request.method_string() << ' ' << request.target();
+
+ response.result(http::status::unauthorized);
+- response.set(http::field::www_authenticate, "Basic realm=\"Icinga 2\"");
+- response.set(http::field::connection, "close");
++ HttpUtility::Set(response, http::field::www_authenticate, "Basic realm=\"Icinga 2\"");
++ HttpUtility::Set(response, http::field::connection, "close");
+
+ if (request[http::field::accept] == "application/json") {
+ HttpUtility::SendJsonBody(response, nullptr, new Dictionary({
+@@ -329,9 +329,9 @@ bool EnsureAuthenticatedUser(
+ { "status", "Unauthorized. Please check your user credentials." }
+ }));
+ } else {
+- response.set(http::field::content_type, "text/html");
++ HttpUtility::Set(response, http::field::content_type, "text/html");
+ response.body() = "<h1>Unauthorized. Please check your user credentials.</h1>";
+- response.set(http::field::content_length, response.body().size());
++ HttpUtility::Set(response, http::field::content_length, response.body().size());
+ }
+
+ boost::system::error_code ec;
+@@ -421,12 +421,12 @@ bool EnsureValidBody(
+ { "status", String("Bad Request: ") + ec.message() }
+ }));
+ } else {
+- response.set(http::field::content_type, "text/html");
++ HttpUtility::Set(response, http::field::content_type, "text/html");
+ response.body() = String("<h1>Bad Request</h1><p><pre>") + ec.message() + "</pre></p>";
+- response.set(http::field::content_length, response.body().size());
++ HttpUtility::Set(response, http::field::content_length, response.body().size());
+ }
+
+- response.set(http::field::connection, "close");
++ HttpUtility::Set(response, http::field::connection, "close");
+
+ http::async_write(stream, response, yc[ec]);
+ stream.async_flush(yc[ec]);
+@@ -511,7 +511,7 @@ void HttpServerConnection::ProcessMessages(boost::asio::yield_context yc)
+ parser.header_limit(1024 * 1024);
+ parser.body_limit(-1);
+
+- response.set(http::field::server, l_ServerHeader);
++ HttpUtility::Set(response, http::field::server, l_ServerHeader);
+
+ if (!EnsureValidHeaders(*m_Stream, buf, parser, response, m_ShuttingDown, yc)) {
+ break;
+diff --git a/lib/remote/httputility.cpp b/lib/remote/httputility.cpp
+index 91902ba501..e46e990ecf 100644
+--- a/lib/remote/httputility.cpp
++++ b/lib/remote/httputility.cpp
+@@ -56,9 +56,9 @@ void HttpUtility::SendJsonBody(boost::beast::http::response<boost::beast::http::
+ {
+ namespace http = boost::beast::http;
+
+- response.set(http::field::content_type, "application/json");
++ HttpUtility::Set(response, http::field::content_type, "application/json");
+ response.body() = JsonEncode(val, params && GetLastParameter(params, "pretty"));
+- response.set(http::field::content_length, response.body().size());
++ HttpUtility::Set(response, http::field::content_length, response.body().size());
+ }
+
+ void HttpUtility::SendJsonError(boost::beast::http::response<boost::beast::http::string_body>& response,
+diff --git a/lib/remote/httputility.hpp b/lib/remote/httputility.hpp
+index 6465b4af92..be600d4090 100644
+--- a/lib/remote/httputility.hpp
++++ b/lib/remote/httputility.hpp
+@@ -5,8 +5,12 @@
+
+ #include "remote/url.hpp"
+ #include "base/dictionary.hpp"
++#include "base/string.hpp"
+ #include <boost/beast/http.hpp>
++#include <boost/lexical_cast.hpp>
+ #include <string>
++#include <type_traits>
++#include <utility>
+
+ namespace icinga
+ {
+@@ -26,6 +30,30 @@ class HttpUtility
+ static void SendJsonBody(boost::beast::http::response<boost::beast::http::string_body>& response, const Dictionary::Ptr& params, const Value& val);
+ static void SendJsonError(boost::beast::http::response<boost::beast::http::string_body>& response, const Dictionary::Ptr& params, const int code,
+ const String& verbose = String(), const String& diagnosticInformation = String());
++
++ template<class Message, class Key, class Value, typename std::enable_if<std::is_arithmetic<Value>::value, int>::type = 0>
++ static void Set(Message& message, Key&& key, Value value)
++ {
++ Set(message, std::forward<Key>(key), boost::lexical_cast<std::string>(value));
++ }
++
++ template<class Message, class Key>
++ static void Set(Message& message, Key&& key, const String& value)
++ {
++ Set(message, std::forward<Key>(key), value.GetData());
++ }
++
++ template<class Message, class Key>
++ static void Set(Message& message, Key&& key, String&& value)
++ {
++ Set(message, std::forward<Key>(key), value.GetData());
++ }
++
++ template<class Message, class Key, class Value, typename std::enable_if<!std::is_arithmetic<Value>::value, int>::type = 0>
++ static void Set(Message& message, Key&& key, Value&& value)
++ {
++ message.set(std::forward<Key>(key), std::forward<Value>(value));
++ }
+ };
+
+ }
+diff --git a/lib/remote/infohandler.cpp b/lib/remote/infohandler.cpp
+index 18c18c0e04..daec628047 100644
+--- a/lib/remote/infohandler.cpp
++++ b/lib/remote/infohandler.cpp
+@@ -29,7 +29,7 @@ bool InfoHandler::HandleRequest(
+
+ if (url->GetPath().empty()) {
+ response.result(http::status::found);
+- response.set(http::field::location, "/v1");
++ HttpUtility::Set(response, http::field::location, "/v1");
+ return true;
+ }
+
+@@ -74,7 +74,7 @@ bool InfoHandler::HandleRequest(
+
+ HttpUtility::SendJsonBody(response, params, result);
+ } else {
+- response.set(http::field::content_type, "text/html");
++ HttpUtility::Set(response, http::field::content_type, "text/html");
+
+ String body = "<html><head><title>Icinga 2</title></head><h1>Hello from Icinga 2 (Version: " + Application::GetAppVersion() + ")!</h1>";
+ body += "<p>You are authenticated as <b>" + user->GetName() + "</b>. ";
+@@ -92,7 +92,7 @@ bool InfoHandler::HandleRequest(
+
+ body += R"(<p>More information about API requests is available in the <a href="https://icinga.com/docs/icinga2/latest/" target="_blank">documentation</a>.</p></html>)";
+ response.body() = body;
+- response.set(http::field::content_length, response.body().size());
++ HttpUtility::Set(response, http::field::content_length, response.body().size());
+ }
+
+ return true;
+diff --git a/plugins/check_nscp_api.cpp b/plugins/check_nscp_api.cpp
+index 3f6843ec29..ad15e62527 100644
+--- a/plugins/check_nscp_api.cpp
++++ b/plugins/check_nscp_api.cpp
+@@ -16,6 +16,7 @@
+ #include "base/tcpsocket.hpp" /* include global icinga::Connect */
+ #include "base/tlsstream.hpp"
+ #include "base/base64.hpp"
++#include "remote/httputility.hpp"
+ #include "remote/url.hpp"
+ #include <remote/url-characters.hpp>
+ #include <boost/program_options.hpp>
+@@ -365,11 +366,11 @@ static Dictionary::Ptr FetchData(const String& host, const String& port, const S
+
+ http::request<http::string_body> request (http::verb::get, std::string(url->Format(true)), 10);
+
+- request.set(http::field::user_agent, "Icinga/check_nscp_api/" + String(VERSION));
+- request.set(http::field::host, host + ":" + port);
++ HttpUtility::Set(request, http::field::user_agent, "Icinga/check_nscp_api/" + String(VERSION));
++ HttpUtility::Set(request, http::field::host, host + ":" + port);
+
+- request.set(http::field::accept, "application/json");
+- request.set("password", password);
++ HttpUtility::Set(request, http::field::accept, "application/json");
++ HttpUtility::Set(request, "password", password);
+
+ if (l_Debug) {
+ std::cout << "Sending request to " << url->Format(false, false) << "'.\n";
+From 7e62a68eadada58e762d3f4261750796adffd440 Mon Sep 17 00:00:00 2001
+From: "Alexander A. Klimov" <alexander.klimov@icinga.com>
+Date: Wed, 26 Aug 2020 13:48:39 +0200
+Subject: [PATCH] Define BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
+
+refs #8185
+---
+ CMakeLists.txt | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 046f23cf22..46e765415e 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -172,6 +172,9 @@ add_definitions(-DBOOST_COROUTINES_NO_DEPRECATION_WARNING)
+
+ add_definitions(-DBOOST_FILESYSTEM_NO_DEPRECATED)
+
++# Required for Boost v1.74+
++add_definitions(-DBOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT)
++
+ link_directories(${Boost_LIBRARY_DIRS})
+ include_directories(${Boost_INCLUDE_DIRS})
+
diff --git a/net-analyzer/icinga2/icinga2-2.12.1.ebuild b/net-analyzer/icinga2/icinga2-2.12.1.ebuild
new file mode 100644
index 000000000000..8ec76ee82fac
--- /dev/null
+++ b/net-analyzer/icinga2/icinga2-2.12.1.ebuild
@@ -0,0 +1,149 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit cmake systemd
+
+if [[ ${PV} != 9999 ]]; then
+ SRC_URI="https://github.com/Icinga/icinga2/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+ KEYWORDS="~amd64 ~arm64 ~x86"
+else
+ inherit git-r3
+ EGIT_REPO_URI="https://github.com/Icinga/icinga2.git"
+fi
+
+DESCRIPTION="Distributed, general purpose, network monitoring engine"
+HOMEPAGE="https://icinga.com/"
+
+LICENSE="GPL-2"
+SLOT="0"
+IUSE="console jumbo-build libressl lto mail mariadb minimal +mysql nano-syntax +plugins postgres systemd +vim-syntax"
+
+# Add accounts to DEPEND because of fowners in src_install
+DEPEND="
+ !libressl? ( dev-libs/openssl:0= )
+ libressl? ( dev-libs/libressl:0= )
+ >=dev-libs/boost-1.66.0:=[context]
+ console? ( dev-libs/libedit )
+ mariadb? ( dev-db/mariadb-connector-c:= )
+ mysql? ( dev-db/mysql-connector-c:= )
+ postgres? ( dev-db/postgresql:= )
+ dev-libs/yajl:=
+ acct-user/icinga
+ acct-group/icinga
+ acct-group/icingacmd"
+BDEPEND="
+ sys-devel/bison
+ >=sys-devel/flex-2.5.35"
+RDEPEND="
+ ${DEPEND}
+ plugins? ( || (
+ net-analyzer/monitoring-plugins
+ net-analyzer/nagios-plugins
+ ) )
+ mail? ( virtual/mailx )
+ acct-group/nagios"
+
+REQUIRED_USE="!minimal? ( || ( mariadb mysql postgres ) )"
+
+PATCHES=(
+ # https://github.com/Icinga/icinga2/issues/8185#issuecomment-680875875
+ "${FILESDIR}/${PN}-2.12.1-boost-1.74.0.patch"
+)
+
+src_configure() {
+ local mycmakeargs=(
+ -DICINGA2_UNITY_BUILD=$(usex jumbo-build)
+ -DCMAKE_INSTALL_SYSCONFDIR=/etc
+ -DCMAKE_INSTALL_LOCALSTATEDIR=/var
+ -DICINGA2_SYSCONFIGFILE=/etc/conf.d/icinga2
+ -DICINGA2_PLUGINDIR="/usr/$(get_libdir)/nagios/plugins"
+ -DICINGA2_USER=icinga
+ -DICINGA2_GROUP=icingacmd
+ -DICINGA2_COMMAND_GROUP=icingacmd
+ -DICINGA2_RUNDIR=/run
+ -DINSTALL_SYSTEMD_SERVICE_AND_INITSCRIPT=ON
+ -DUSE_SYSTEMD=$(usex systemd)
+ -DLOGROTATE_HAS_SU=ON
+ -DICINGA2_LTO_BUILD=$(usex lto)
+ )
+ # default to off if minimal, allow the flags to be set otherwise
+ if use minimal; then
+ mycmakeargs+=(
+ -DICINGA2_WITH_MYSQL=OFF
+ -DICINGA2_WITH_PGSQL=OFF
+ )
+ else
+ mycmakeargs+=(
+ -DICINGA2_WITH_PGSQL=$(usex postgres)
+ -DICINGA2_WITH_MYSQL=$(usex mysql yes $(usex mariadb))
+ )
+ fi
+
+ cmake_src_configure
+}
+
+src_install() {
+ cmake_src_install
+
+ newinitd "${FILESDIR}"/icinga2.initd-3 icinga2
+
+ if use mysql || use mariadb; then
+ docinto schema
+ newdoc "${WORKDIR}"/icinga2-${PV}/lib/db_ido_mysql/schema/mysql.sql mysql.sql
+ docinto schema/upgrade
+ dodoc "${WORKDIR}"/icinga2-${PV}/lib/db_ido_mysql/schema/upgrade/*
+ fi
+ if use postgres; then
+ docinto schema
+ newdoc "${WORKDIR}"/icinga2-${PV}/lib/db_ido_pgsql/schema/pgsql.sql pgsql.sql
+ docinto schema/upgrade
+ dodoc "${WORKDIR}"/icinga2-${PV}/lib/db_ido_pgsql/schema/upgrade/*
+ fi
+
+ keepdir /etc/icinga2
+ keepdir /var/lib/icinga2/api/zones
+ keepdir /var/lib/icinga2/api/repository
+ keepdir /var/lib/icinga2/api/log
+ keepdir /var/spool/icinga2/perfdata
+
+ rm -r "${D}/run" || die "failed to remove /run"
+ rm -r "${D}/var/cache" || die "failed to remove /var/cache"
+
+ fowners root:icinga /etc/icinga2
+ fperms 0750 /etc/icinga2
+ fowners icinga:icinga /var/lib/icinga2
+ fowners icinga:icinga /var/spool/icinga2
+ fowners -R icinga:icingacmd /var/lib/icinga2/api
+ fowners icinga:icinga /var/spool/icinga2/perfdata
+ fowners icinga:icingacmd /var/log/icinga2
+
+ fperms ug+rwX,o-rwx /etc/icinga2
+ fperms ug+rwX,o-rwx /var/lib/icinga2
+ fperms ug+rwX,o-rwx /var/spool/icinga2
+ fperms ug+rwX,o-rwx /var/log/icinga2
+
+ if use vim-syntax; then
+ insinto /usr/share/vim/vimfiles
+ doins -r "${WORKDIR}"/${P}/tools/syntax/vim/ftdetect
+ doins -r "${WORKDIR}"/${P}/tools/syntax/vim/syntax
+ fi
+
+ if use nano-syntax; then
+ insinto /usr/share/nano
+ doins "${WORKDIR}"/${P}/tools/syntax/nano/icinga2.nanorc
+ fi
+}
+
+pkg_postinst() {
+ if [[ "${PV}" != 9999 ]]; then
+ local v
+ for v in ${REPLACING_VERSIONS}; do
+ if ver_test "${PV}" -gt "${v}"; then
+ elog "DB IDO schema upgrade may be required."
+ elog "https://www.icinga.com/docs/icinga2/latest/doc/16-upgrading-icinga-2/"
+ fi
+ done
+ fi
+}
diff --git a/net-analyzer/icinga2/metadata.xml b/net-analyzer/icinga2/metadata.xml
index 2916a6886755..15c8f7859e8a 100644
--- a/net-analyzer/icinga2/metadata.xml
+++ b/net-analyzer/icinga2/metadata.xml
@@ -8,6 +8,7 @@
<use>
<flag name="console">Adds support for line-editing in the console</flag>
<flag name="lto">Adds support for link time optimization</flag>
+ <flag name="jumbo-build">Combine source files to speed up build process (may speed up build but requires more memory)</flag>
<flag name="mail">Allows for mailing of alerts</flag>
<flag name="mariadb">Enable support for the mariadb database backend</flag>
<flag name="nano-syntax">Adds support for syntax used in the nano editor</flag>