ConfigStagesHandler: Don't allow concurrent package updates anymore

To prevent Icinga2 from being restarted while
one or more requests are still in progress and end up
as corrupted stages without status file and startup logs.
This commit is contained in:
Yonas Habteab 2022-03-07 17:52:08 +01:00
parent 362adcab1a
commit 6193a911bf
2 changed files with 13 additions and 1 deletions

View File

@ -5,12 +5,15 @@
#include "remote/httputility.hpp"
#include "remote/filterutility.hpp"
#include "base/application.hpp"
#include "base/defer.hpp"
#include "base/exception.hpp"
using namespace icinga;
REGISTER_URLHANDLER("/v1/config/stages", ConfigStagesHandler);
std::atomic<bool> ConfigStagesHandler::m_RunningPackageUpdates (false);
bool ConfigStagesHandler::HandleRequest(
AsioTlsStream& stream,
const ApiUser::Ptr& user,
@ -128,12 +131,19 @@ void ConfigStagesHandler::HandlePost(
if (reload && !activate)
BOOST_THROW_EXCEPTION(std::invalid_argument("Parameter 'reload' must be false when 'activate' is false."));
if (m_RunningPackageUpdates.exchange(true)) {
return HttpUtility::SendJsonError(response, params, 423,
"Conflicting request, there is already an ongoing package update in progress. Please try it again later.");
}
auto resetPackageUpdates (Shared<Defer>::Make([]() { ConfigStagesHandler::m_RunningPackageUpdates.store(false); }));
std::unique_lock<std::mutex> lock(ConfigPackageUtility::GetStaticPackageMutex());
stageName = ConfigPackageUtility::CreateStage(packageName, files);
/* validate the config. on success, activate stage and reload */
ConfigPackageUtility::AsyncTryActivateStage(packageName, stageName, activate, reload);
ConfigPackageUtility::AsyncTryActivateStage(packageName, stageName, activate, reload, resetPackageUpdates);
} catch (const std::exception& ex) {
return HttpUtility::SendJsonError(response, params, 500,
"Stage creation failed.",

View File

@ -4,6 +4,7 @@
#define CONFIGSTAGESHANDLER_H
#include "remote/httphandler.hpp"
#include <atomic>
namespace icinga
{
@ -47,6 +48,7 @@ private:
const Dictionary::Ptr& params
);
static std::atomic<bool> m_RunningPackageUpdates;
};
}