Implement support for upgrading NSIS-based installations

refs #11449
This commit is contained in:
Gunnar Beutner 2016-04-01 08:25:36 +02:00
parent b0264dba3b
commit 327d12295c
7 changed files with 87 additions and 40 deletions

View File

@ -82,10 +82,7 @@ if(NOT WIN32)
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/bash_completion.d DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/bash_completion.d
) )
else() else()
install( install_if_not_exists(icinga2/features-enabled/mainlog.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled)
FILES icinga2/features-enabled/mainlog.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled
)
endif() endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")

View File

@ -125,15 +125,16 @@ int Main(void)
#ifdef _WIN32 #ifdef _WIN32
bool builtinPaths = true; bool builtinPaths = true;
String prefix = Utility::GetIcingaInstallPath(); String binaryPrefix = Utility::GetIcingaInstallPath();
String dataPrefix = Utility::GetIcingaDataPath();
if (!prefix.IsEmpty()) { if (!binaryPrefix.IsEmpty() && !dataPrefix.IsEmpty()) {
Application::DeclarePrefixDir(prefix); Application::DeclarePrefixDir(binaryPrefix);
Application::DeclareSysconfDir(prefix + "\\etc"); Application::DeclareSysconfDir(dataPrefix + "\\etc");
Application::DeclareRunDir(prefix + "\\var\\run"); Application::DeclareRunDir(dataPrefix + "\\var\\run");
Application::DeclareLocalStateDir(prefix + "\\var"); Application::DeclareLocalStateDir(dataPrefix + "\\var");
Application::DeclarePkgDataDir(prefix + "\\share\\icinga2"); Application::DeclarePkgDataDir(binaryPrefix + "\\share\\icinga2");
Application::DeclareIncludeConfDir(prefix + "\\share\\icinga2\\include"); Application::DeclareIncludeConfDir(binaryPrefix + "\\share\\icinga2\\include");
} else { } else {
Log(LogWarning, "icinga-app", "Registry key could not be read. Falling back to built-in paths."); Log(LogWarning, "icinga-app", "Registry key could not be read. Falling back to built-in paths.");

View File

@ -23,7 +23,7 @@
using namespace icinga; using namespace icinga;
static String GetIcingaInstallDir(void) static String GetIcingaInstallPath(void)
{ {
char szFileName[MAX_PATH]; char szFileName[MAX_PATH];
if (!GetModuleFileName(NULL, szFileName, sizeof(szFileName))) if (!GetModuleFileName(NULL, szFileName, sizeof(szFileName)))
@ -59,12 +59,12 @@ static bool ExecuteCommand(const String& app, const String& arguments)
static bool ExecuteIcingaCommand(const String& arguments) static bool ExecuteIcingaCommand(const String& arguments)
{ {
return ExecuteCommand(GetIcingaInstallDir() + "\\sbin\\icinga2.exe", arguments); return ExecuteCommand(GetIcingaInstallPath() + "\\sbin\\icinga2.exe", arguments);
} }
static void CopyConfigFile(const String& installDir, const String& sourceConfigPath, size_t skelPrefixLength) static void CopyConfigFile(const String& installDir, const String& sourceConfigPath, size_t skelPrefixLength)
{ {
String relativeConfigPath = sourceConfigPath.SubStr(installDir.GetLength() + skelPrefixLength); String relativeConfigPath = sourceConfigPath.SubStr(skelPrefixLength);
String targetConfigPath = installDir + relativeConfigPath; String targetConfigPath = installDir + relativeConfigPath;
@ -74,29 +74,74 @@ static void CopyConfigFile(const String& installDir, const String& sourceConfigP
} }
} }
static String GetNSISInstallPath(void)
{
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Icinga Development Team\\ICINGA2", 0,
KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS) {
BYTE pvData[MAX_PATH];
DWORD cbData = sizeof(pvData) - 1;
DWORD lType;
if (RegQueryValueEx(hKey, NULL, NULL, &lType, pvData, &cbData) == ERROR_SUCCESS && lType == REG_SZ) {
pvData[cbData] = '\0';
return (char *)pvData;
}
RegCloseKey(hKey);
}
return "";
}
static int UpgradeNSIS(void)
{
String installPath = GetNSISInstallPath();
if (installPath.IsEmpty())
return 0;
if (!Utility::PathExists(installPath + "\\uninstall.exe"))
return 0;
ExecuteCommand(installPath + "\\uninstall.exe", "/S");
String dataPath = Utility::GetIcingaDataPath();
if (!Utility::PathExists(dataPath))
CreateSymbolicLink(dataPath.CStr(), installPath.CStr(), SYMBOLIC_LINK_FLAG_DIRECTORY);
return 0;
}
static int InstallIcinga(void) static int InstallIcinga(void)
{ {
String installDir = GetIcingaInstallDir(); UpgradeNSIS();
ExecuteCommand("icacls", "\"" + installDir + "\" /grant *S-1-5-20:(oi)(ci)m"); String installDir = GetIcingaInstallPath();
ExecuteCommand("icacls", "\"" + installDir + "\\etc\" /inheritance:r /grant:r *S-1-5-20:(oi)(ci)m *S-1-5-32-544:(oi)(ci)f"); String dataDir = Utility::GetIcingaDataPath();
Utility::MkDirP(installDir + "/etc/icinga2/pki", 0700); Utility::MkDirP(dataDir, 0700);
Utility::MkDirP(installDir + "/var/cache/icinga2", 0700);
Utility::MkDirP(installDir + "/var/lib/icinga2/pki", 0700); ExecuteCommand("icacls", "\"" + dataDir + "\" /grant *S-1-5-20:(oi)(ci)m");
Utility::MkDirP(installDir + "/var/lib/icinga2/agent/inventory", 0700); ExecuteCommand("icacls", "\"" + dataDir + "\\etc\" /inheritance:r /grant:r *S-1-5-20:(oi)(ci)m *S-1-5-32-544:(oi)(ci)f");
Utility::MkDirP(installDir + "/var/lib/icinga2/api/config", 0700);
Utility::MkDirP(installDir + "/var/lib/icinga2/api/log", 0700); Utility::MkDirP(dataDir + "/etc/icinga2/pki", 0700);
Utility::MkDirP(installDir + "/var/lib/icinga2/api/zones", 0700); Utility::MkDirP(dataDir + "/var/cache/icinga2", 0700);
Utility::MkDirP(installDir + "/var/lib/icinga2/api/zones", 0700); Utility::MkDirP(dataDir + "/var/lib/icinga2/pki", 0700);
Utility::MkDirP(installDir + "/var/log/icinga2/compat/archive", 0700); Utility::MkDirP(dataDir + "/var/lib/icinga2/agent/inventory", 0700);
Utility::MkDirP(installDir + "/var/log/icinga2/crash", 0700); Utility::MkDirP(dataDir + "/var/lib/icinga2/api/config", 0700);
Utility::MkDirP(installDir + "/var/run/icinga2/cmd", 0700); Utility::MkDirP(dataDir + "/var/lib/icinga2/api/log", 0700);
Utility::MkDirP(installDir + "/var/spool/icinga2/perfdata", 0700); Utility::MkDirP(dataDir + "/var/lib/icinga2/api/zones", 0700);
Utility::MkDirP(installDir + "/var/spool/icinga2/tmp", 0700); Utility::MkDirP(dataDir + "/var/lib/icinga2/api/zones", 0700);
Utility::MkDirP(dataDir + "/var/log/icinga2/compat/archive", 0700);
Utility::MkDirP(dataDir + "/var/log/icinga2/crash", 0700);
Utility::MkDirP(dataDir + "/var/run/icinga2/cmd", 0700);
Utility::MkDirP(dataDir + "/var/spool/icinga2/perfdata", 0700);
Utility::MkDirP(dataDir + "/var/spool/icinga2/tmp", 0700);
String skelDir = "/share/skel"; String skelDir = "/share/skel";
Utility::GlobRecursive(installDir + skelDir, "*", boost::bind(&CopyConfigFile, installDir, _1, skelDir.GetLength()), GlobFile); Utility::GlobRecursive(installDir + skelDir, "*", boost::bind(&CopyConfigFile, dataDir, _1, installDir.GetLength() + skelDir.GetLength()), GlobFile);
ExecuteIcingaCommand("--scm-install daemon"); ExecuteIcingaCommand("--scm-install daemon");

View File

@ -56,6 +56,7 @@
# include <windows.h> # include <windows.h>
# include <io.h> # include <io.h>
# include <msi.h> # include <msi.h>
# include <shlobj.h>
#endif /*_WIN32*/ #endif /*_WIN32*/
using namespace icinga; using namespace icinga;
@ -1883,4 +1884,12 @@ String Utility::GetIcingaInstallPath(void)
return ""; return "";
} }
String Utility::GetIcingaDataPath(void)
{
char path[MAX_PATH];
if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, path)))
return "";
return String(path) + "\\icinga2";
}
#endif /* _WIN32 */ #endif /* _WIN32 */

View File

@ -145,6 +145,7 @@ public:
#ifdef _WIN32 #ifdef _WIN32
static String GetIcingaInstallPath(void); static String GetIcingaInstallPath(void);
static String GetIcingaDataPath(void);
#endif /* _WIN32 */ #endif /* _WIN32 */
private: private:

View File

@ -45,10 +45,7 @@ if(NOT WIN32)
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled\")") 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/checker.conf \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled/checker.conf\")")
else() else()
install( install_if_not_exists(${PROJECT_SOURCE_DIR}/etc/icinga2/features-enabled/checker.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled)
FILES ${PROJECT_SOURCE_DIR}/etc/icinga2/features-enabled/checker.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled
)
endif() endif()
install( install(

View File

@ -45,10 +45,7 @@ if(NOT WIN32)
install(CODE "file(MAKE_DIRECTORY \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled\")") 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/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/notification.conf \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled/notification.conf\")")
else() else()
install( install_if_not_exists(${PROJECT_SOURCE_DIR}/etc/icinga2/features-enabled/notification.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled)
FILES ${PROJECT_SOURCE_DIR}/etc/icinga2/features-enabled/notification.conf
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled
)
endif() endif()
install(TARGETS notification RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/icinga2) install(TARGETS notification RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/icinga2)