From b14a48d519ce1c89c2261b67c033f5a0a19fa329 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sun, 22 Nov 2015 12:36:50 +0100 Subject: [PATCH] Implement Platform* global variables refs #10693 --- doc/18-language-reference.md | 6 +- icinga-app/icinga.cpp | 6 + lib/base/application.cpp | 125 +---------------- lib/base/utility.cpp | 254 ++++++++++++++++++++++++++++++++++- lib/base/utility.hpp | 6 + 5 files changed, 273 insertions(+), 124 deletions(-) diff --git a/doc/18-language-reference.md b/doc/18-language-reference.md index 43e1f520d..7a2f2cde6 100644 --- a/doc/18-language-reference.md +++ b/doc/18-language-reference.md @@ -371,7 +371,11 @@ NodeName |**Read-write.** Contains the cluster node name. Set to the UseVfork |**Read-write.** Whether to use vfork(). Only available on *NIX. Defaults to true. AttachDebugger |**Read-write.** Whether to attach a debugger when Icinga 2 crashes. Defaults to false. RunAsUser |**Read-write.** Defines the user the Icinga 2 daemon is running as. Used in the `init.conf` configuration file. -RunAsGroup |**Read-write.** Defines the group the Icinga 2 daemon is running as. Used in the `init.conf` configuration file. +RunAsGroup |**Read-write.** Defines the group the Icinga 2 daemon is running as. Used in the `init.conf` configuration file. +PlatformName |**Read-only.** The name of the operating system, e.g. "Ubuntu". +PlatformVersion |**Read-only.** The version of the operating system, e.g. "14.04.3 LTS". +PlatformKernel |**Read-only.** The name of the operating system kernel, e.g. "Linux". +PlatformKernelVersion|**Read-only.** The version of the operating system kernel, e.g. "3.13.0-63-generic". ## Apply diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index 2b154d1ce..b6bfb31b8 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -176,6 +176,12 @@ int Main(void) ScriptGlobal::Set("AttachDebugger", false); + ScriptGlobal::Set("PlatformKernel", Utility::GetPlatformKernel()); + ScriptGlobal::Set("PlatformKernelVersion", Utility::GetPlatformKernelVersion()); + ScriptGlobal::Set("PlatformName", Utility::GetPlatformName()); + ScriptGlobal::Set("PlatformVersion", Utility::GetPlatformVersion()); + ScriptGlobal::Set("PlatformArchitecture", Utility::GetPlatformArchitecture()); + LogSeverity logLevel = Logger::GetConsoleLogSeverity(); Logger::SetConsoleLogSeverity(LogWarning); diff --git a/lib/base/application.cpp b/lib/base/application.cpp index 1000c1a67..e5e9caed6 100644 --- a/lib/base/application.cpp +++ b/lib/base/application.cpp @@ -44,9 +44,6 @@ #ifdef __linux__ #include #endif /* __linux__ */ -#ifdef _WIN32 -#include -#endif /*_WIN32*/ using namespace icinga; @@ -483,107 +480,6 @@ String Application::GetExePath(const String& argv0) #endif /* _WIN32 */ } -#ifndef _WIN32 -static String UnameHelper(char type) -{ - /* Unfortunately the uname() system call doesn't support some of the - * query types we're interested in - so we're using popen() instead. */ - - char cmd[] = "uname -X 2>&1"; - cmd[7] = type; - - FILE *fp = popen(cmd, "r"); - - char line[1024]; - std::ostringstream msgbuf; - - while (fgets(line, sizeof(line), fp) != NULL) - msgbuf << line; - - pclose(fp); - - String result = msgbuf.str(); - - return result.Trim(); -} - -int ReleaseHelper(std::string &result) -{ - /* You are useing *some* distribution */ - FILE *fp = popen("lsb_release -s -d 2>&1", "r"); - std::ostringstream msgbuf; - - if (fp != NULL) { - char line[1024]; - while (fgets(line, sizeof(line), fp) != NULL) - msgbuf << line; - int status = pclose(fp); - if (WEXITSTATUS(status) == 0) { - result = msgbuf.str(); - boost::trim(result); - return result.length(); - } - } - - /* You have systemd or Ubuntu etc. */ - std::ifstream release("/etc/os-release"); - std::string release_line; - if (release.is_open()) { - while (getline(release, release_line)) { - if (release_line.find("PRETTY_NAME") != std::string::npos) { - result = release_line.substr(13, release_line.length() - 14); - return result.length(); - } - } - } - - /* Centos < 7 */ - release.close(); - release.open("/etc/redhat-release"); - if (release.is_open()) { - getline(release, release_line); - result = release_line; - return result.length(); - } - - /* sles 11 sp3, opensuse w/e */ - release.close(); - release.open("etc/SuSE-release"); - if (release.is_open()) { - getline(release, release_line); - result = release_line; - return result.length(); - } - - /* Just give up */ - return 0; -} - -#else -static String WindowsVersionHelper() -{ - //Minimum required Version, the installer/user is in the responsibility to take care of that - String winver = "Windows Vista"; - if (IsWindowsVistaSP1OrGreater()) - winver = "Windows Vista SP1"; - if (IsWindowsVistaSP2OrGreater()) - winver = "Windows Vista SP2"; - if (IsWindows7OrGreater()) - winver = "Windows 7"; - if (IsWindows7SP1OrGreater()) - winver = "Windows 7 SP1"; - if (IsWindows8OrGreater()) - winver = "Windows 8"; - if (IsWindows8Point1OrGreater()) - winver = "Windows 8.1 or greater"; - if (IsWindowsServer()) - winver += " (Server)"; - - return winver; -} - -#endif /* _WIN32 */ - /** * Display version and path information. */ @@ -605,24 +501,13 @@ void Application::DisplayInfoMessage(std::ostream& os, bool skipVersion) << " Vars path: " << GetVarsPath() << "\n" << " PID path: " << GetPidPath() << "\n"; -#ifndef _WIN32 os << "\n" << "System information:" << "\n" - << " Operating system: " << UnameHelper('s') << "\n" - << " Operating system version: " << UnameHelper('r') << "\n" - << " Architecture: " << UnameHelper('m') << "\n"; -#else - os << "\n" - << "System information:\n" - << " Operating system: Windows\n" - << " Operating system version: " << WindowsVersionHelper() << "\n"; -#endif /* _WIN32 */ - -#ifdef __linux__ - std::string release; - if (ReleaseHelper(release)) - os << " Distribution: " << release << "\n"; -#endif /* __linux__ */ + << " Platform: " << Utility::GetPlatformName() << "\n" + << " Platform version: " << Utility::GetPlatformVersion() << "\n" + << " Kernel: " << Utility::GetPlatformKernel() << "\n" + << " Kernel version: " << Utility::GetPlatformKernelVersion() << "\n" + << " Architecture: " << Utility::GetPlatformArchitecture() << "\n"; } /** diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index 2a88a44be..32ea82022 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -46,11 +46,14 @@ #endif /* HAVE_CXXABI_H */ #ifndef _WIN32 -# include -# include -# include +# include +# include +# include #endif /* _WIN32 */ +#ifdef _WIN32 +# include +#endif /*_WIN32*/ using namespace icinga; @@ -1405,3 +1408,248 @@ String Utility::UnescapeString(const String& s) return result.str(); } + +#ifndef _WIN32 +static String UnameHelper(char type) +{ + /* Unfortunately the uname() system call doesn't support some of the + * query types we're interested in - so we're using popen() instead. */ + + char cmd[] = "uname -X 2>&1"; + cmd[7] = type; + + FILE *fp = popen(cmd, "r"); + + char line[1024]; + std::ostringstream msgbuf; + + while (fgets(line, sizeof(line), fp) != NULL) + msgbuf << line; + + pclose(fp); + + String result = msgbuf.str(); + + return result.Trim(); +} +#endif /* _WIN32 */ +static bool ReleaseHelper(String *platformName, String *platformVersion) +{ +#ifdef _WIN32 + if (platformName) + *platformName = "Windows"; + + if (platformVersion) { + String *platformVersion = "Vista"; + if (IsWindowsVistaSP1OrGreater()) + *platformVersion = "Vista SP1"; + if (IsWindowsVistaSP2OrGreater()) + *platformVersion = "Vista SP2"; + if (IsWindows7OrGreater()) + *platformVersion = "7"; + if (IsWindows7SP1OrGreater()) + *platformVersion = "7 SP1"; + if (IsWindows8OrGreater()) + *platformVersion = "8"; + if (IsWindows8Point1OrGreater()) + *platformVersion = "8.1 or greater"; + if (IsWindowsServer()) + *platformVersion += " (Server)"; + } + + return true; +#else /* _WIN32 */ + if (platformName) + *platformName = "Unknown"; + + if (platformVersion) + *platformVersion = "Unknown"; + + /* You are using a distribution which supports LSB. */ + FILE *fp = popen("lsb_release -s -i 2>&1", "r"); + + if (fp != NULL) { + std::ostringstream msgbuf; + char line[1024]; + while (fgets(line, sizeof(line), fp) != NULL) + msgbuf << line; + int status = pclose(fp); + if (WEXITSTATUS(status) == 0) { + if (platformName) + *platformName = msgbuf.str(); + } + } + + fp = popen("lsb_release -s -r 2>&1", "r"); + + if (fp != NULL) { + std::ostringstream msgbuf; + char line[1024]; + while (fgets(line, sizeof(line), fp) != NULL) + msgbuf << line; + int status = pclose(fp); + if (WEXITSTATUS(status) == 0) { + if (platformVersion) + *platformVersion = msgbuf.str(); + } + } + + /* OS X */ + fp = popen("sw_vers -productName 2>&1", "r"); + + if (fp != NULL) { + std::ostringstream msgbuf; + char line[1024]; + while (fgets(line, sizeof(line), fp) != NULL) + msgbuf << line; + int status = pclose(fp); + if (WEXITSTATUS(status) == 0) { + String info = msgbuf.str(); + info = info.Trim(); + + if (platformName) + *platformName = info; + } + } + + fp = popen("sw_vers -productVersion 2>&1", "r"); + + if (fp != NULL) { + std::ostringstream msgbuf; + char line[1024]; + while (fgets(line, sizeof(line), fp) != NULL) + msgbuf << line; + int status = pclose(fp); + if (WEXITSTATUS(status) == 0) { + String info = msgbuf.str(); + info = info.Trim(); + + if (platformVersion) + *platformVersion = info; + + return true; + } + } + + /* You have systemd or Ubuntu etc. */ + std::ifstream release("/etc/os-release"); + if (release.is_open()) { + std::string release_line; + while (getline(release, release_line)) { + if (platformName) { + if (release_line.find("NAME") != std::string::npos) { + *platformName = release_line.substr(6, release_line.length() - 7); + } + } + + if (platformVersion) { + if (release_line.find("VERSION") != std::string::npos) { + *platformVersion = release_line.substr(8, release_line.length() - 9); + } + } + } + + return true; + } + + /* Centos < 7 */ + release.close(); + release.open("/etc/redhat-release"); + if (release.is_open()) { + std::string release_line; + getline(release, release_line); + + String info = release_line; + + if (platformName) + *platformName = info.SubStr(0, info.FindFirstOf(" ")); + + if (platformVersion) + *platformVersion = info.SubStr(info.FindFirstOf(" ") + 1); + + return true; + } + + /* sles 11 sp3, opensuse w/e */ + release.close(); + release.open("/etc/SuSE-release"); + if (release.is_open()) { + std::string release_line; + getline(release, release_line); + + String info = release_line; + + if (platformName) + *platformName = info.SubStr(0, info.FindFirstOf(" ")); + + if (platformVersion) + *platformVersion = info.SubStr(info.FindFirstOf(" ") + 1); + + return true; + } + + /* Just give up */ + return false; +#endif /* _WIN32 */ +} + +String Utility::GetPlatformKernel(void) +{ +#ifdef _WIN32 + return "Windows"; +#else /* _WIN32 */ + return UnameHelper('s'); +#endif /* _WIN32 */ +} + +String Utility::GetPlatformKernelVersion(void) +{ +#ifdef _WIN32 + OSVERSIONINFO info; + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&info); + + std::ostringstream msgbuf; + msgbuf << info.dwMajorVersion << "." << info.dwMinorVersion; + + return msgbuf.str(); +#else /* _WIN32 */ + return UnameHelper('r'); +#endif /* _WIN32 */ +} + +String Utility::GetPlatformName(void) +{ + String platformName; + if (!ReleaseHelper(&platformName, NULL)) + return "Unknown"; + return platformName; +} + +String Utility::GetPlatformVersion(void) +{ + String platformVersion; + if (!ReleaseHelper(NULL, &platformVersion)) + return "Unknown"; + return platformVersion; +} + +String Utility::GetPlatformArchitecture(void) +{ +#ifdef _WIN32 + SYSTEM_INFO info; + GetNativeSystemInfo(&info); + switch (info.wProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_AMD64: + return "x86_64"; + case PROCESSOR_ARCHITECTURE_ARM: + return "arm"; + case PROCESSOR_ARCHITECTURE_INTEL: + return "x86"; + default: + return "unknown"; + } +#else /* _WIN32 */ + return UnameHelper('m'); +#endif /* _WIN32 */ +} diff --git a/lib/base/utility.hpp b/lib/base/utility.hpp index 0dbfc6e60..3a44c176b 100644 --- a/lib/base/utility.hpp +++ b/lib/base/utility.hpp @@ -133,6 +133,12 @@ public: static Value LoadJsonFile(const String& path); static void SaveJsonFile(const String& path, const Value& value); + static String GetPlatformKernel(void); + static String GetPlatformKernelVersion(void); + static String GetPlatformName(void); + static String GetPlatformVersion(void); + static String GetPlatformArchitecture(void); + private: Utility(void); static void CollectPaths(const String& path, std::vector& paths); -- 2.40.0