Merge pull request #5547 from ryanohnemus/feature/allow_package_upload_without_restart

Add optional reload parameter to config stage upload
This commit is contained in:
Michael Friedrich 2017-09-20 14:30:22 +02:00 committed by GitHub
commit 27b49b07ed
4 changed files with 24 additions and 13 deletions

View File

@ -1381,7 +1381,8 @@ Stages provide a way to maintain multiple configuration versions for a package.
Send a `POST` request to the URL endpoint `/v1/config/stages` and add the name of an existing
configuration package to the URL path (e.g. `example-cmdb`).
The request body must contain the `files` attribute with the value being
a dictionary of file targets and their content.
a dictionary of file targets and their content. You can also specify an optional `reload` attribute
that will tell icinga2 to reload after stage config validation. By default this is set to `true`.
The file path requires one of these two directories inside its path:
@ -1412,7 +1413,7 @@ intentional.
"code": 200.0,
"package": "example-cmdb",
"stage": "example.localdomain-1441625839-0",
"status": "Created stage."
"status": "Created stage. Icinga2 will reload."
}
]
}
@ -1420,9 +1421,10 @@ intentional.
The Icinga 2 API returns the `package` name this stage was created for, and also
generates a unique name for the `stage` attribute you'll need for later requests.
Icinga 2 automatically restarts the daemon in order to activate the new config stage.
If the validation for the new config stage failed, the old stage and its configuration objects
will remain active.
Icinga 2 automatically restarts the daemon in order to activate the new config stage. This
can be disabled by setting `reload` to `false` in the request.
If the validation for the new config stage failed, the old stage
and its configuration objects will remain active.
> **Note**
>

View File

@ -176,7 +176,7 @@ void ConfigPackageUtility::ActivateStage(const String& packageName, const String
WritePackageConfig(packageName);
}
void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, const String& packageName, const String& stageName)
void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, const String& packageName, const String& stageName, bool reload)
{
String logFile = GetPackageDir() + "/" + packageName + "/" + stageName + "/startup.log";
std::ofstream fpLog(logFile.CStr(), std::ofstream::out | std::ostream::binary | std::ostream::trunc);
@ -191,6 +191,8 @@ void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, con
/* validation went fine, activate stage and reload */
if (pr.ExitStatus == 0) {
ActivateStage(packageName, stageName);
if (reload)
Application::RequestRestart();
} else {
Log(LogCritical, "ConfigPackageUtility")
@ -199,7 +201,7 @@ void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, con
}
}
void ConfigPackageUtility::AsyncTryActivateStage(const String& packageName, const String& stageName)
void ConfigPackageUtility::AsyncTryActivateStage(const String& packageName, const String& stageName, bool reload)
{
VERIFY(Application::GetArgC() >= 1);
@ -213,7 +215,7 @@ void ConfigPackageUtility::AsyncTryActivateStage(const String& packageName, cons
Process::Ptr process = new Process(Process::PrepareCommand(args));
process->SetTimeout(300);
process->Run(boost::bind(&TryActivateStageCallback, _1, packageName, stageName));
process->Run(boost::bind(&TryActivateStageCallback, _1, packageName, stageName, reload));
}
void ConfigPackageUtility::DeleteStage(const String& packageName, const String& stageName)

View File

@ -51,7 +51,7 @@ public:
static std::vector<String> GetStages(const String& packageName);
static String GetActiveStage(const String& packageName);
static void ActivateStage(const String& packageName, const String& stageName);
static void AsyncTryActivateStage(const String& packageName, const String& stageName);
static void AsyncTryActivateStage(const String& packageName, const String& stageName, bool reload);
static std::vector<std::pair<String, bool> > GetFiles(const String& packageName, const String& stageName);
@ -65,7 +65,7 @@ private:
static void WritePackageConfig(const String& packageName);
static void WriteStageConfig(const String& packageName, const String& stageName);
static void TryActivateStageCallback(const ProcessResult& pr, const String& packageName, const String& stageName);
static void TryActivateStageCallback(const ProcessResult& pr, const String& packageName, const String& stageName, bool reload);
};
}

View File

@ -98,6 +98,10 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
if (!ConfigPackageUtility::ValidateName(packageName))
return HttpUtility::SendJsonError(response, 400, "Invalid package name.");
bool reload = true;
if (params->Contains("reload"))
reload = HttpUtility::GetLastParameter(params, "reload");
Dictionary::Ptr files = params->Get("files");
String stageName;
@ -109,7 +113,7 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
stageName = ConfigPackageUtility::CreateStage(packageName, files);
/* validate the config. on success, activate stage and reload */
ConfigPackageUtility::AsyncTryActivateStage(packageName, stageName);
ConfigPackageUtility::AsyncTryActivateStage(packageName, stageName, reload);
} catch (const std::exception& ex) {
return HttpUtility::SendJsonError(response, 500,
"Stage creation failed.",
@ -118,10 +122,13 @@ void ConfigStagesHandler::HandlePost(const ApiUser::Ptr& user, HttpRequest& requ
Dictionary::Ptr result1 = new Dictionary();
String responseStatus = "Created stage. ";
responseStatus += (reload ? " Icinga2 will reload." : " Icinga2 reload skipped.");
result1->Set("package", packageName);
result1->Set("stage", stageName);
result1->Set("code", 200);
result1->Set("status", "Created stage.");
result1->Set("status", responseStatus);
Array::Ptr results = new Array();
results->Add(result1);