mirror of https://github.com/Icinga/icinga2.git
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:
parent
362adcab1a
commit
6193a911bf
|
@ -5,12 +5,15 @@
|
||||||
#include "remote/httputility.hpp"
|
#include "remote/httputility.hpp"
|
||||||
#include "remote/filterutility.hpp"
|
#include "remote/filterutility.hpp"
|
||||||
#include "base/application.hpp"
|
#include "base/application.hpp"
|
||||||
|
#include "base/defer.hpp"
|
||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
|
|
||||||
using namespace icinga;
|
using namespace icinga;
|
||||||
|
|
||||||
REGISTER_URLHANDLER("/v1/config/stages", ConfigStagesHandler);
|
REGISTER_URLHANDLER("/v1/config/stages", ConfigStagesHandler);
|
||||||
|
|
||||||
|
std::atomic<bool> ConfigStagesHandler::m_RunningPackageUpdates (false);
|
||||||
|
|
||||||
bool ConfigStagesHandler::HandleRequest(
|
bool ConfigStagesHandler::HandleRequest(
|
||||||
AsioTlsStream& stream,
|
AsioTlsStream& stream,
|
||||||
const ApiUser::Ptr& user,
|
const ApiUser::Ptr& user,
|
||||||
|
@ -128,12 +131,19 @@ 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."));
|
||||||
|
|
||||||
|
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());
|
std::unique_lock<std::mutex> lock(ConfigPackageUtility::GetStaticPackageMutex());
|
||||||
|
|
||||||
stageName = ConfigPackageUtility::CreateStage(packageName, files);
|
stageName = ConfigPackageUtility::CreateStage(packageName, files);
|
||||||
|
|
||||||
/* validate the config. on success, activate stage and reload */
|
/* 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) {
|
} catch (const std::exception& ex) {
|
||||||
return HttpUtility::SendJsonError(response, params, 500,
|
return HttpUtility::SendJsonError(response, params, 500,
|
||||||
"Stage creation failed.",
|
"Stage creation failed.",
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#define CONFIGSTAGESHANDLER_H
|
#define CONFIGSTAGESHANDLER_H
|
||||||
|
|
||||||
#include "remote/httphandler.hpp"
|
#include "remote/httphandler.hpp"
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace icinga
|
namespace icinga
|
||||||
{
|
{
|
||||||
|
@ -47,6 +48,7 @@ private:
|
||||||
const Dictionary::Ptr& params
|
const Dictionary::Ptr& params
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static std::atomic<bool> m_RunningPackageUpdates;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue