]> granicus.if.org Git - icinga2/commitdiff
Implement support for upgrading NSIS-based installations
authorGunnar Beutner <gunnar@beutner.name>
Fri, 1 Apr 2016 06:25:36 +0000 (08:25 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Wed, 20 Apr 2016 08:07:51 +0000 (10:07 +0200)
refs #11449

etc/CMakeLists.txt
icinga-app/icinga.cpp
icinga-installer/icinga-installer.cpp
lib/base/utility.cpp
lib/base/utility.hpp
lib/checker/CMakeLists.txt
lib/notification/CMakeLists.txt

index f97674c3b8bfa226662a966b9b5e27429fe8d06c..3c39df7f60f2fc5715bb5fa371fcaf7ea0d01a42 100644 (file)
@@ -83,10 +83,7 @@ if(NOT WIN32)
     DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/bash_completion.d
   )
 else()
-  install(
-    FILES icinga2/features-enabled/mainlog.conf
-    DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled
-  )
+  install_if_not_exists(icinga2/features-enabled/mainlog.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled)
 endif()
 
 if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
index 2f465bd0b34a3cf9ff1761f21e0cce756f1db3bc..75ef69578ec7d38e6fe465e493f6a4564d833cf2 100644 (file)
@@ -125,15 +125,16 @@ int Main(void)
 #ifdef _WIN32
        bool builtinPaths = true;
 
-       String prefix = Utility::GetIcingaInstallPath();
-
-       if (!prefix.IsEmpty()) {
-               Application::DeclarePrefixDir(prefix);
-               Application::DeclareSysconfDir(prefix + "\\etc");
-               Application::DeclareRunDir(prefix + "\\var\\run");
-               Application::DeclareLocalStateDir(prefix + "\\var");
-               Application::DeclarePkgDataDir(prefix + "\\share\\icinga2");
-               Application::DeclareIncludeConfDir(prefix + "\\share\\icinga2\\include");
+       String binaryPrefix = Utility::GetIcingaInstallPath();
+       String dataPrefix = Utility::GetIcingaDataPath();
+
+       if (!binaryPrefix.IsEmpty() && !dataPrefix.IsEmpty()) {
+               Application::DeclarePrefixDir(binaryPrefix);
+               Application::DeclareSysconfDir(dataPrefix + "\\etc");
+               Application::DeclareRunDir(dataPrefix + "\\var\\run");
+               Application::DeclareLocalStateDir(dataPrefix + "\\var");
+               Application::DeclarePkgDataDir(binaryPrefix + "\\share\\icinga2");
+               Application::DeclareIncludeConfDir(binaryPrefix + "\\share\\icinga2\\include");
        } else {
                Log(LogWarning, "icinga-app", "Registry key could not be read. Falling back to built-in paths.");
 
index 764f47b53fbbef6e089833b49b1558cb67471c51..a91c8b3ff1c677c524c6b2c2191a862323c0802c 100644 (file)
@@ -23,7 +23,7 @@
 
 using namespace icinga;
 
-static String GetIcingaInstallDir(void)
+static String GetIcingaInstallPath(void)
 {
        char szFileName[MAX_PATH];
        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)
 {
-       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)
 {
-       String relativeConfigPath = sourceConfigPath.SubStr(installDir.GetLength() + skelPrefixLength);
+       String relativeConfigPath = sourceConfigPath.SubStr(skelPrefixLength);
 
        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)
 {
-       String installDir = GetIcingaInstallDir();
-
-       ExecuteCommand("icacls", "\"" + installDir + "\" /grant *S-1-5-20:(oi)(ci)m");
-       ExecuteCommand("icacls", "\"" + installDir + "\\etc\" /inheritance:r /grant:r *S-1-5-20:(oi)(ci)m *S-1-5-32-544:(oi)(ci)f");
-
-       Utility::MkDirP(installDir + "/etc/icinga2/pki", 0700);
-       Utility::MkDirP(installDir + "/var/cache/icinga2", 0700);
-       Utility::MkDirP(installDir + "/var/lib/icinga2/pki", 0700);
-       Utility::MkDirP(installDir + "/var/lib/icinga2/agent/inventory", 0700);
-       Utility::MkDirP(installDir + "/var/lib/icinga2/api/config", 0700);
-       Utility::MkDirP(installDir + "/var/lib/icinga2/api/log", 0700);
-       Utility::MkDirP(installDir + "/var/lib/icinga2/api/zones", 0700);
-       Utility::MkDirP(installDir + "/var/lib/icinga2/api/zones", 0700);
-       Utility::MkDirP(installDir + "/var/log/icinga2/compat/archive", 0700);
-       Utility::MkDirP(installDir + "/var/log/icinga2/crash", 0700);
-       Utility::MkDirP(installDir + "/var/run/icinga2/cmd", 0700);
-       Utility::MkDirP(installDir + "/var/spool/icinga2/perfdata", 0700);
-       Utility::MkDirP(installDir + "/var/spool/icinga2/tmp", 0700);
+       UpgradeNSIS();
+
+       String installDir = GetIcingaInstallPath();
+       String dataDir = Utility::GetIcingaDataPath();
+
+       Utility::MkDirP(dataDir, 0700);
+
+       ExecuteCommand("icacls", "\"" + dataDir + "\" /grant *S-1-5-20:(oi)(ci)m");
+       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(dataDir + "/etc/icinga2/pki", 0700);
+       Utility::MkDirP(dataDir + "/var/cache/icinga2", 0700);
+       Utility::MkDirP(dataDir + "/var/lib/icinga2/pki", 0700);
+       Utility::MkDirP(dataDir + "/var/lib/icinga2/agent/inventory", 0700);
+       Utility::MkDirP(dataDir + "/var/lib/icinga2/api/config", 0700);
+       Utility::MkDirP(dataDir + "/var/lib/icinga2/api/log", 0700);
+       Utility::MkDirP(dataDir + "/var/lib/icinga2/api/zones", 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";
-       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");
 
index 8d6466839f31c430d832c50d6e8860208c23e261..0b09516b759258e5bc946cd4f3452d4e6539680c 100644 (file)
@@ -56,6 +56,7 @@
 #      include <windows.h>
 #      include <io.h>
 #      include <msi.h>
+#      include <shlobj.h>
 #endif /*_WIN32*/
 
 using namespace icinga;
@@ -1883,4 +1884,12 @@ String Utility::GetIcingaInstallPath(void)
        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 */
\ No newline at end of file
index 9af1b8f8a09a8d1b02ceda80fdf404dfb8bc8660..c1c50cc53bf01b202afbd066ba212c0b506d3bbb 100644 (file)
@@ -145,6 +145,7 @@ public:
 
 #ifdef _WIN32
        static String GetIcingaInstallPath(void);
+       static String GetIcingaDataPath(void);
 #endif /* _WIN32 */
 
 private:
index 8777e06404dcb5a34dac26c4f9507d881980aa83..cdbf1a9a5f681cdcbefa0c39a35decf4cc95c8e7 100644 (file)
@@ -45,10 +45,7 @@ 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\")")
 else()
-  install(
-    FILES ${PROJECT_SOURCE_DIR}/etc/icinga2/features-enabled/checker.conf
-    DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled
-  )
+  install_if_not_exists(${PROJECT_SOURCE_DIR}/etc/icinga2/features-enabled/checker.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled)
 endif()
 
 install(
index f05180149dc2c819b80b7cc7467f956b46979889..22ebb482b4948e5558ce5866258871553a7926a4 100644 (file)
@@ -45,10 +45,7 @@ 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/notification.conf \"\$ENV{DESTDIR}${CMAKE_INSTALL_FULL_SYSCONFDIR}/icinga2/features-enabled/notification.conf\")")
 else()
-  install(
-    FILES ${PROJECT_SOURCE_DIR}/etc/icinga2/features-enabled/notification.conf
-    DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled
-  )
+  install_if_not_exists(${PROJECT_SOURCE_DIR}/etc/icinga2/features-enabled/notification.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/features-enabled)
 endif()
 
 install(TARGETS notification RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/icinga2)