set(CPACK_PACKAGE_EXECUTABLES "Icinga2SetupAgent;Icinga 2 Agent Wizard")
set(CPACK_NSIS_MUI_FINISHPAGE_RUN "Icinga2SetupAgent")
set(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS "nsExec::Exec 'net stop icinga2'")
-set(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS "${CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS}\nSleep 10000")
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}\nnsExec::Exec 'icacls \\\"$INSTDIR\\\" /grant NetworkService:(oi)(ci)m'")
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}\nnsExec::Exec 'icacls \\\"$INSTDIR\\\\etc\\\" /inheritance:r /grant:r NetworkService:(oi)(ci)m /grant:r Administrators:(oi)(ci)f'")
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}\nCreateDirectory '$INSTDIR\\\\etc\\\\icinga2\\\\pki'")
namespace po = boost::program_options;
#ifdef _WIN32
-SERVICE_STATUS l_SvcStatus;
-SERVICE_STATUS_HANDLE l_SvcStatusHandle;
+static SERVICE_STATUS l_SvcStatus;
+static SERVICE_STATUS_HANDLE l_SvcStatusHandle;
+static HANDLE l_Job;
#endif /* _WIN32 */
static std::vector<String> GetLogLevelCompletionSuggestions(const String& arg)
{
if (dwCtrl == SERVICE_CONTROL_STOP) {
ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
- Application::RequestShutdown();
+ TerminateJobObject(l_Job, 0);
}
}
ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);
- int rc = Main();
+ l_Job = CreateJobObject(NULL, NULL);
- ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, rc);
+ for (;;) {
+ LPSTR arg = argv[0];
+ String args;
+ int uargc = Application::GetArgC();
+ char **uargv = Application::GetArgV();
- Application::Exit(rc);
+ args += Utility::EscapeShellArg(Application::GetExePath(uargv[0]));
+
+ for (int i = 2; i < uargc && uargv[i]; i++) {
+ if (args != "")
+ args += " ";
+
+ args += Utility::EscapeShellArg(uargv[i]);
+ }
+
+ STARTUPINFO si = { sizeof(si) };
+ PROCESS_INFORMATION pi;
+
+ char *uargs = strdup(args.CStr());
+
+ BOOL res = CreateProcess(NULL, uargs, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+
+ free(uargs);
+
+ if (!res)
+ break;
+
+ CloseHandle(pi.hThread);
+
+ AssignProcessToJobObject(l_Job, pi.hProcess);
+
+ if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0)
+ break;
+
+ DWORD exitStatus;
+
+ if (!GetExitCodeProcess(pi.hProcess, &exitStatus))
+ break;
+
+ if (exitStatus != 7)
+ break;
+ }
+
+ TerminateJobObject(l_Job, 0);
+
+ CloseHandle(l_Job);
+
+ ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
+
+ Application::Exit(0);
}
#endif /* _WIN32 */
/* Nothing to do here. */
}
-static void ReloadProcessCallback(const ProcessResult& pr)
+static void ReloadProcessCallbackInternal(const ProcessResult& pr)
{
if (pr.ExitStatus != 0)
Log(LogCritical, "Application", "Found error in config: reloading aborted");
+#ifdef _WIN32
+ else
+ Application::Exit(7); /* keep this exit code in sync with icinga-app */
+#endif /* _WIN32 */
+}
+
+static void ReloadProcessCallback(const ProcessResult& pr)
+{
l_Restarting = false;
+
+ boost::thread t(boost::bind(&ReloadProcessCallbackInternal, pr));
+ t.detach();
}
pid_t Application::StartReloadProcess(void)
else
i++; // the next parameter after --reload-internal is the pid, remove that too
}
+
+#ifndef _WIN32
args->Add("--reload-internal");
args->Add(Convert::ToString(Utility::GetPid()));
+#else /* _WIN32 */
+ args->Add("--validate");
+#endif /* _WIN32 */
Process::Ptr process = new Process(Process::PrepareCommand(args));
process->SetTimeout(300);