Fix NSIS installer and Windows service.

Refs #4865
This commit is contained in:
Gunnar Beutner 2014-04-18 12:14:21 +02:00
parent 4a3ca90a51
commit 0fb55f3404
11 changed files with 152 additions and 100 deletions

View File

@ -40,13 +40,6 @@ file(READ "${CMAKE_CURRENT_SOURCE_DIR}/COPYING.Exceptions" ICINGA2_LICENSE_ADDIT
set(ICINGA2_LICENSE "${ICINGA2_LICENSE_GPL}\n\n---\n\n${ICINGA2_LICENSE_ADDITIONS}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt" ${ICINGA2_LICENSE})
set(CPACK_PACKAGE_CONTACT "Icinga Development Team")
set(CPACK_PACKAGE_VERSION ${ICINGA2_VERSION})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt")
set(CPACK_WIX_UPGRADE_GUID "68C75073-7CEF-4FC9-8DA5-581758729696")
set(CPACK_SOURCE_IGNORE_FILES "/.git/" "/debian/" "/.vagrant/" "/release/" "/debug/" "/build/" )
include(CPack)
include(GetGitRevisionDescription)
git_describe(GIT_VERSION --tags)
if(GIT_VERSION MATCHES "-NOTFOUND$")
@ -56,13 +49,16 @@ else()
configure_file(${CMAKE_CURRENT_BINARY_DIR}/icinga-version.h ${CMAKE_CURRENT_SOURCE_DIR}/icinga-version.h.fallback COPYONLY)
endif()
set(CPACK_PACKAGE_CONTACT "Icinga Development Team")
set(CPACK_PACKAGE_NAME "Icinga2")
set(CPACK_PACKAGE_VENDOR "Icinga Development Team")
set(CPACK_PACKAGE_VERSION ${ICINGA2_VERSION})
set(CPACK_NSIS_DISPLAY_NAME "Icinga 2")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "ICINGA2")
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icinga-app\\\\icinga.ico")
set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icinga-app\\\\icinga.ico")
set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/icinga-app\\\\icinga.ico")
set(CPACK_NSIS_INSTALLED_ICON_NAME "sbin\\\\icinga2.exe")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt")
set(CPACK_WIX_UPGRADE_GUID "68C75073-7CEF-4FC9-8DA5-581758729696")
set(CPACK_SOURCE_IGNORE_FILES "/.git/" "/debian/" "/.vagrant/" "/release/" "/debug/" "/build/" )
include(CPack)

View File

@ -1,25 +0,0 @@
function(install_if_not_exists src dest)
if(NOT IS_ABSOLUTE "${src}")
set(src "${CMAKE_CURRENT_SOURCE_DIR}/${src}")
endif()
get_filename_component(src_name "${src}" NAME)
if (NOT IS_ABSOLUTE "${dest}")
set(dest "${CMAKE_INSTALL_PREFIX}/${dest}")
endif()
install(CODE "
if(NOT EXISTS \"\$ENV{DESTDIR}${dest}/${src_name}\")
#file(INSTALL \"${src}\" DESTINATION \"${dest}\")
message(STATUS \"Installing: \$ENV{DESTDIR}${dest}/${src_name}\")
execute_process(COMMAND \${CMAKE_COMMAND} -E copy \"${src}\"
\"\$ENV{DESTDIR}${dest}/${src_name}\"
RESULT_VARIABLE copy_result
ERROR_VARIABLE error_output)
if(copy_result)
message(FATAL_ERROR \${error_output})
endif()
else()
message(STATUS \"Skipping : \$ENV{DESTDIR}${dest}/${src_name}\")
endif()
")
endfunction(install_if_not_exists)

View File

@ -15,60 +15,74 @@
# along with this program; if not, write to the Free Software Foundation
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
include(InstallConfig)
configure_file(icinga/icinga-classic-apache.conf.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga/icinga-classic-apache.conf)
install_if_not_exists(icinga2/icinga2.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
install_if_not_exists(icinga2/constants.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
install_if_not_exists(icinga2/conf.d/commands.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
install_if_not_exists(icinga2/conf.d/downtimes.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
install_if_not_exists(icinga2/conf.d/generic-host.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
install_if_not_exists(icinga2/conf.d/generic-service.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
install_if_not_exists(icinga2/conf.d/generic-user.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
install_if_not_exists(icinga2/conf.d/groups.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
install_if_not_exists(icinga2/conf.d/hosts/localhost.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts)
install_if_not_exists(icinga2/conf.d/hosts/localhost/disk.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost)
install_if_not_exists(icinga2/conf.d/hosts/localhost/http.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost)
install_if_not_exists(icinga2/conf.d/hosts/localhost/icinga.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost)
install_if_not_exists(icinga2/conf.d/hosts/localhost/kernel.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost)
install_if_not_exists(icinga2/conf.d/hosts/localhost/load.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost)
install_if_not_exists(icinga2/conf.d/hosts/localhost/processes.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost)
install_if_not_exists(icinga2/conf.d/hosts/localhost/ssh.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost)
install_if_not_exists(icinga2/conf.d/hosts/localhost/swap.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost)
install_if_not_exists(icinga2/conf.d/hosts/localhost/users.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost)
install_if_not_exists(icinga2/conf.d/notifications.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
install_if_not_exists(icinga2/conf.d/timeperiods.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
install_if_not_exists(icinga2/conf.d/users.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
install_if_not_exists(icinga2/features-available/agent.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/checker.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/command.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/compatlog.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/debuglog.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/graphite.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/ido-mysql.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/ido-pgsql.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/livestatus.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/mainlog.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/notification.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/perfdata.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/statusdata.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/features-available/syslog.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available)
install_if_not_exists(icinga2/scripts/check_kernel ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/scripts)
install_if_not_exists(icinga2/scripts/mail-host-notification.sh ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/scripts)
install_if_not_exists(icinga2/scripts/mail-service-notification.sh ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/scripts)
install_if_not_exists(logrotate.d/icinga2 ${CMAKE_INSTALL_SYSCONFDIR}/logrotate.d)
install(
FILES icinga2/icinga2.conf icinga2/constants.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2
)
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled\")")
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink ../features-available/checker.conf \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled/checker.conf\")")
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink ../features-available/notification.conf \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled/notification.conf\")")
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink ../features-available/mainlog.conf \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled/mainlog.conf\")")
install(
FILES icinga2/conf.d/commands.conf icinga2/conf.d/downtimes.conf icinga2/conf.d/generic-host.conf
icinga2/conf.d/generic-service.conf icinga2/conf.d/generic-user.conf icinga2/conf.d/groups.conf
icinga2/conf.d/notifications.conf icinga2/conf.d/timeperiods.conf icinga2/conf.d/users.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d
)
install(
FILES icinga2/conf.d/hosts/localhost.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts
)
install(
FILES icinga2/conf.d/hosts/localhost/disk.conf icinga2/conf.d/hosts/localhost/http.conf
icinga2/conf.d/hosts/localhost/icinga.conf icinga2/conf.d/hosts/localhost/kernel.conf
icinga2/conf.d/hosts/localhost/load.conf icinga2/conf.d/hosts/localhost/processes.conf
icinga2/conf.d/hosts/localhost/ssh.conf icinga2/conf.d/hosts/localhost/swap.conf
icinga2/conf.d/hosts/localhost/users.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d/hosts/localhost
)
install(
FILES icinga2/features-available/agent.conf icinga2/features-available/checker.conf
icinga2/features-available/command.conf icinga2/features-available/compatlog.conf
icinga2/features-available/debuglog.conf icinga2/features-available/graphite.conf
icinga2/features-available/ido-mysql.conf icinga2/features-available/ido-pgsql.conf
icinga2/features-available/livestatus.conf icinga2/features-available/mainlog.conf
icinga2/features-available/notification.conf icinga2/features-available/perfdata.conf
icinga2/features-available/statusdata.conf icinga2/features-available/syslog.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-available
)
install(
FILES icinga2/scripts/check_kernel icinga2/scripts/mail-host-notification.sh
icinga2/scripts/mail-service-notification.sh
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/scripts
)
install(
FILES logrotate.d/icinga2
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/logrotate.d
)
if(NOT WIN32)
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled\")")
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink ../features-available/checker.conf \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled/checker.conf\")")
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink ../features-available/notification.conf \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled/notification.conf\")")
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink ../features-available/mainlog.conf \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled/mainlog.conf\")")
else()
install(
FILES icinga2/features-enabled/checker.conf icinga2/features-enabled/notification.conf
icinga2/features-enabled/mainlog.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled
)
endif()
if(NOT WIN32)
configure_file(init.d/icinga2.cmake ${CMAKE_CURRENT_BINARY_DIR}/init.d/icinga2)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/init.d/icinga2
DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/init.d
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/init.d
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
endif()

View File

@ -417,16 +417,7 @@ int Main(void)
#ifdef _WIN32
static int SetupService(bool install, int argc, char **argv)
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR szPath[MAX_PATH * 5];
if (!GetModuleFileName(NULL, szPath, MAX_PATH)) {
printf("Cannot install service (%d)\n", GetLastError());
return 1;
}
schSCManager = OpenSCManager(
SC_HANDLE schSCManager = OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS);
@ -436,15 +427,20 @@ static int SetupService(bool install, int argc, char **argv)
return 1;
}
strcat(szPath, " --scm");
TCHAR szPath[MAX_PATH];
for (int i = 0; i < argc; i++) {
strcat(szPath, " \"");
strcat(szPath, argv[i]);
strcat(szPath, "\"");
if (!GetModuleFileName(NULL, szPath, MAX_PATH)) {
printf("Cannot install service (%d)\n", GetLastError());
return 1;
}
schService = OpenService(schSCManager, "icinga2", DELETE);
String szArgs;
szArgs = Utility::EscapeShellArg(szPath) + " --scm";
for (int i = 0; i < argc; i++)
szArgs += " " + Utility::EscapeShellArg(argv[i]);
SC_HANDLE schService = OpenService(schSCManager, "icinga2", DELETE);
if (schService != NULL) {
if (!DeleteService(schService)) {
@ -469,7 +465,7 @@ static int SetupService(bool install, int argc, char **argv)
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
szPath,
szArgs.CStr(),
NULL,
NULL,
NULL,

View File

@ -201,6 +201,44 @@ shared_ptr<X509> GetX509Certificate(const String& pemfile)
return shared_ptr<X509>(cert, X509_free);
}
int MakeX509CSR(const char *cn, const char *keyfile, const char *csrfile)
{
InitializeOpenSSL();
RSA *rsa = RSA_generate_key(4096, RSA_F4, NULL, NULL);
BIO *bio = BIO_new(BIO_s_file());
BIO_write_filename(bio, const_cast<char *>(keyfile));
PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL);
BIO_free(bio);
X509_REQ *req = X509_REQ_new();
if (!req)
return 0;
EVP_PKEY *key = EVP_PKEY_new();
EVP_PKEY_assign_RSA(key, rsa);
X509_REQ_set_version(req, 0);
X509_REQ_set_pubkey(req, key);
X509_NAME *name = X509_REQ_get_subject_name(req);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)cn, -1, -1, 0);
X509_REQ_sign(req, key, EVP_sha1());
EVP_PKEY_free(key);
bio = BIO_new(BIO_s_file());
BIO_write_filename(bio, const_cast<char *>(csrfile));
PEM_write_bio_X509_REQ(bio, req);
BIO_free(bio);
X509_REQ_free(req);
return 1;
}
String SHA256(const String& s)
{
SHA256_CTX context;

View File

@ -37,6 +37,7 @@ shared_ptr<SSL_CTX> I2_BASE_API MakeSSLContext(const String& pubkey, const Strin
void I2_BASE_API AddCRLToSSLContext(const shared_ptr<SSL_CTX>& context, const String& crlPath);
String I2_BASE_API GetCertificateCN(const shared_ptr<X509>& certificate);
shared_ptr<X509> I2_BASE_API GetX509Certificate(const String& pemfile);
extern "C" int I2_BASE_API MakeX509CSR(const char *cn, const char *keyfile, const char *csrfile);
String I2_BASE_API SHA256(const String& s);
class I2_BASE_API openssl_error : virtual public std::exception, virtual public boost::exception { };

View File

@ -772,6 +772,37 @@ String Utility::EscapeShellCmd(const String& s)
return result;
}
String Utility::EscapeShellArg(const String& s)
{
String result;
#ifdef _WIN32
result = "\"";
#else /* _WIN32 */
result = "'";
#endif /* _WIN32 */
BOOST_FOREACH(char ch, s) {
#ifdef _WIN32
if (ch == '"' || ch == '%') {
result += ' ';
}
#else /* _WIN32 */
if (ch == '\') {
result += "'\\'";
#endif
result += ch;
}
#ifdef _WIN32
result += '"';
#else /* _WIN32 */
result += '\'';
#endif /* _WIN32 */
return result;
}
#ifdef _WIN32
static void WindowsSetThreadName(const char *name)
{

View File

@ -101,6 +101,7 @@ public:
static void SetNonBlockingSocket(SOCKET s);
static String EscapeShellCmd(const String& s);
static String EscapeShellArg(const String& s);
static void SetThreadName(const String& name, bool os = true);
static String GetThreadName(void);

View File

@ -51,7 +51,7 @@ void PluginCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRes
resolvers.push_back(std::make_pair("command", commandObj));
resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, checkable->GetLastCheckResult(), Utility::EscapeShellCmd);
Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, checkable->GetLastCheckResult(), Utility::EscapeShellArg);
Dictionary::Ptr envMacros = make_shared<Dictionary>();

View File

@ -48,7 +48,7 @@ void PluginEventTask::ScriptFunc(const Checkable::Ptr& checkable)
resolvers.push_back(std::make_pair("command", commandObj));
resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, checkable->GetLastCheckResult(), Utility::EscapeShellCmd);
Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, checkable->GetLastCheckResult(), Utility::EscapeShellArg);
Dictionary::Ptr envMacros = make_shared<Dictionary>();

View File

@ -63,7 +63,7 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, c
resolvers.push_back(std::make_pair("command", commandObj));
resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance()));
Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, cr, Utility::EscapeShellCmd);
Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, cr, Utility::EscapeShellArg);
Dictionary::Ptr envMacros = make_shared<Dictionary>();