Disallow stage deletions during reload

Once the new worker process has read the config, it also includes a
`include */include.conf` statement within the config packages root
directory, and from there on we must not allow to delete any stage
directory from the config package. Otherwise, when the worker actually
evaluates that include statement, it will fail to find the directory
where the include file is located, or the `active.conf` file, which is
included from each stage's `include.conf` file, thus causing the worker
fail.

Co-Authored-By: Johannes Schmidt <johannes.schmidt@icinga.com>
This commit is contained in:
Yonas Habteab 2025-07-22 11:25:03 +02:00
parent 1ac4d83963
commit ce3275d27f
2 changed files with 26 additions and 0 deletions

View File

@ -2,6 +2,7 @@
#include "remote/configpackageshandler.hpp" #include "remote/configpackageshandler.hpp"
#include "remote/configpackageutility.hpp" #include "remote/configpackageutility.hpp"
#include "remote/configobjectslock.hpp"
#include "remote/httputility.hpp" #include "remote/httputility.hpp"
#include "remote/filterutility.hpp" #include "remote/filterutility.hpp"
#include "base/exception.hpp" #include "base/exception.hpp"
@ -111,6 +112,12 @@ void ConfigPackagesHandler::HandlePost(
return; return;
} }
ConfigObjectsSharedLock configObjectsSharedLock(std::try_to_lock);
if (!configObjectsSharedLock) {
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
return;
}
try { try {
std::unique_lock<std::mutex> lock(ConfigPackageUtility::GetStaticPackageMutex()); std::unique_lock<std::mutex> lock(ConfigPackageUtility::GetStaticPackageMutex());
@ -157,6 +164,12 @@ void ConfigPackagesHandler::HandleDelete(
return; return;
} }
ConfigObjectsSharedLock lock(std::try_to_lock);
if (!lock) {
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
return;
}
try { try {
ConfigPackageUtility::DeletePackage(packageName); ConfigPackageUtility::DeletePackage(packageName);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {

View File

@ -2,6 +2,7 @@
#include "remote/configstageshandler.hpp" #include "remote/configstageshandler.hpp"
#include "remote/configpackageutility.hpp" #include "remote/configpackageutility.hpp"
#include "remote/configobjectslock.hpp"
#include "remote/httputility.hpp" #include "remote/httputility.hpp"
#include "remote/filterutility.hpp" #include "remote/filterutility.hpp"
#include "base/application.hpp" #include "base/application.hpp"
@ -135,6 +136,12 @@ void ConfigStagesHandler::HandlePost(
if (reload && !activate) if (reload && !activate)
BOOST_THROW_EXCEPTION(std::invalid_argument("Parameter 'reload' must be false when 'activate' is false.")); BOOST_THROW_EXCEPTION(std::invalid_argument("Parameter 'reload' must be false when 'activate' is false."));
ConfigObjectsSharedLock configObjectsSharedLock(std::try_to_lock);
if (!configObjectsSharedLock) {
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
return;
}
{ {
std::lock_guard runningPackageUpdatesLock(l_RunningPackageUpdatesMutex); std::lock_guard runningPackageUpdatesLock(l_RunningPackageUpdatesMutex);
double currentReloadFailedTime = Application::GetLastReloadFailed(); double currentReloadFailedTime = Application::GetLastReloadFailed();
@ -228,6 +235,12 @@ void ConfigStagesHandler::HandleDelete(
if (!ConfigPackageUtility::ValidateStageName(stageName)) if (!ConfigPackageUtility::ValidateStageName(stageName))
return HttpUtility::SendJsonError(response, params, 400, "Invalid stage name '" + stageName + "'."); return HttpUtility::SendJsonError(response, params, 400, "Invalid stage name '" + stageName + "'.");
ConfigObjectsSharedLock lock(std::try_to_lock);
if (!lock) {
HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading");
return;
}
try { try {
ConfigPackageUtility::DeleteStage(packageName, stageName); ConfigPackageUtility::DeleteStage(packageName, stageName);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {