diff --git a/lib/remote/configstageshandler.cpp b/lib/remote/configstageshandler.cpp index 9d7c23064..b5aaadd6c 100644 --- a/lib/remote/configstageshandler.cpp +++ b/lib/remote/configstageshandler.cpp @@ -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 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::Make([]() { ConfigStagesHandler::m_RunningPackageUpdates.store(false); })); + std::unique_lock 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.", diff --git a/lib/remote/configstageshandler.hpp b/lib/remote/configstageshandler.hpp index c6d644366..88f248c8f 100644 --- a/lib/remote/configstageshandler.hpp +++ b/lib/remote/configstageshandler.hpp @@ -4,6 +4,7 @@ #define CONFIGSTAGESHANDLER_H #include "remote/httphandler.hpp" +#include namespace icinga { @@ -47,6 +48,7 @@ private: const Dictionary::Ptr& params ); + static std::atomic m_RunningPackageUpdates; }; }