diff --git a/.gitattributes b/.gitattributes
index a6ab5f7a5aa..09acedad5ea 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,3 @@
debian/ export-ignore
.gitattributes export-ignore
+icinga-archive-version.cmake export-subst
diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md
index 2d67d00bd1c..df272e26f2d 100644
--- a/.github/ISSUE_TEMPLATE/release.md
+++ b/.github/ISSUE_TEMPLATE/release.md
@@ -9,7 +9,7 @@ assignees: ''
# Release Workflow
-- [ ] Update `ICINGA2_VERSION`
+- [ ] Update `ICINGA2_VERSION` in main CMakeLists.txt
- [ ] Update bundled Windows dependencies
- [ ] Harden global TLS defaults (consult https://ssl-config.mozilla.org)
- [ ] Update `CHANGELOG.md`
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ef59d95ded9..0e0c4fc7fb3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,8 @@
cmake_minimum_required(VERSION 3.17...3.17)
set(BOOST_MIN_VERSION "1.66.0")
+set(ICINGA2_VERSION "2.15.0")
+
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
@@ -54,6 +56,11 @@ set(ICINGA2_GIT_VERSION_INFO ON CACHE BOOL "Whether to use git describe")
set(ICINGA2_UNITY_BUILD ON CACHE BOOL "Whether to perform a unity build")
set(ICINGA2_LTO_BUILD OFF CACHE BOOL "Whether to use LTO")
+option(ICINGA2_INCLUDE_PACKAGE_INFO "Include package version in 'icinga2 --version'" OFF)
+set(ICINGA2_PACKAGE_VERSION ${ICINGA2_VERSION} CACHE STRING "Version used when packaging Icinga 2")
+set(ICINGA2_PACKAGE_REVISION "1" CACHE STRING "Revision used when packaging Icinga 2")
+set(ICINGA2_PACKAGE_VENDOR "Icinga GmbH" CACHE STRING "Vendor string used when packaging Icinga 2")
+
set(ICINGA2_CONFIGDIR "${CMAKE_INSTALL_SYSCONFDIR}/icinga2" CACHE FILEPATH "Main config directory, e.g. /etc/icinga2")
set(ICINGA2_CACHEDIR "${CMAKE_INSTALL_LOCALSTATEDIR}/cache/icinga2" CACHE FILEPATH "Directory for cache files, e.g. /var/cache/icinga2")
set(ICINGA2_DATADIR "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/icinga2" CACHE FILEPATH "Data directory for the daemon, e.g. /var/lib/icinga2")
@@ -97,35 +104,20 @@ file(READ "${CMAKE_CURRENT_SOURCE_DIR}/COPYING" ICINGA2_LICENSE_GPL)
set(ICINGA2_LICENSE "${ICINGA2_LICENSE_GPL}\n\n---\n\n${ICINGA2_LICENSE_ADDITIONS}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt" ${ICINGA2_LICENSE})
-file(STRINGS ICINGA2_VERSION SPEC_VERSION REGEX "^Version:")
-string(LENGTH "${SPEC_VERSION}" SPEC_VERSION_LENGTH)
-math(EXPR SPEC_VERSION_LENGTH "${SPEC_VERSION_LENGTH} - 9")
-string(SUBSTRING ${SPEC_VERSION} 9 ${SPEC_VERSION_LENGTH} SPEC_VERSION)
-
-configure_file(icinga-spec-version.h.cmake icinga-spec-version.h)
-
include(GetGitRevisionDescription)
-git_describe(GIT_VERSION --tags)
-if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/icinga-version.h.force)
- configure_file(icinga-version.h.force ${CMAKE_CURRENT_BINARY_DIR}/icinga-version.h COPYONLY)
-else()
- if(NOT ICINGA2_GIT_VERSION_INFO OR GIT_VERSION MATCHES "-NOTFOUND$")
- file(STRINGS ICINGA2_VERSION SPEC_REVISION REGEX "^Revision: ")
- string(LENGTH "${SPEC_REVISION}" SPEC_REVISION_LENGTH)
- math(EXPR SPEC_REVISION_LENGTH "${SPEC_REVISION_LENGTH} - 10")
- string(SUBSTRING ${SPEC_REVISION} 10 ${SPEC_REVISION_LENGTH} SPEC_REVISION)
-
- set(GIT_VERSION "r${SPEC_VERSION}-${SPEC_REVISION}")
- set(ICINGA2_VERSION "${SPEC_VERSION}")
- else()
- # use GIT version as ICINGA2_VERSION
- string(REGEX REPLACE "^[rv]" "" ICINGA2_VERSION "${GIT_VERSION}")
+git_describe(ICINGA2_VERSION)
+if(NOT ICINGA2_GIT_VERSION_INFO OR ICINGA2_VERSION MATCHES "-NOTFOUND$")
+ include(icinga-archive-version.cmake)
+ if(ICINGA2_VERSION MATCHES "^\\$.*")
+ set(ICINGA2_VERSION "v${ICINGA2_PACKAGE_VERSION}-${ICINGA2_PACKAGE_REVISION}")
endif()
- configure_file(icinga-version.h.cmake icinga-version.h)
endif()
+# We need a version string that doesn't contain the leading 'v' for the icinga.rc file
+string(REGEX REPLACE "^[rv]" "" ICINGA2_RC_VERSION "${ICINGA2_VERSION}")
+
# NuGet on Windows requires a semantic versioning, example: 2.10.4.123 (only 4 element, only numeric)
-string(REGEX REPLACE "-([0-9]+).*$" ".\\1" ICINGA2_VERSION_SAFE "${ICINGA2_VERSION}")
+string(REGEX REPLACE "-([0-9]+).*$" ".\\1" ICINGA2_VERSION_SAFE "${ICINGA2_RC_VERSION}")
string(REGEX REPLACE "-[^\\.]*(.*)$" "\\1" ICINGA2_VERSION_SAFE "${ICINGA2_VERSION_SAFE}")
string(REGEX REPLACE "^([0-9]+\\.[0-9]+\\.[0-9]+)[\\.]?[0-9]*" "\\1" CHOCO_VERSION_SHORT "${ICINGA2_VERSION_SAFE}")
@@ -496,7 +488,7 @@ if(BUILD_TESTING)
endif()
set(CPACK_PACKAGE_NAME "Icinga 2")
-set(CPACK_PACKAGE_VENDOR "Icinga GmbH")
+set(CPACK_PACKAGE_VENDOR ${ICINGA2_PACKAGE_VENDOR})
set(CPACK_PACKAGE_VERSION ${ICINGA2_VERSION_SAFE})
set(CPACK_PACKAGE_INSTALL_DIRECTORY "ICINGA2")
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/icinga-app\\\\icinga.ico")
diff --git a/ICINGA2_VERSION b/ICINGA2_VERSION
deleted file mode 100644
index 66639bc0c36..00000000000
--- a/ICINGA2_VERSION
+++ /dev/null
@@ -1,2 +0,0 @@
-Version: 2.15.0
-Revision: 1
diff --git a/config.h.cmake b/config.h.cmake
index 02ab9d7a007..e8968cf3415 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -28,6 +28,13 @@
#define ICINGA_BUILD_COMPILER_NAME "${ICINGA2_BUILD_COMPILER_NAME}"
#define ICINGA_BUILD_COMPILER_VERSION "${ICINGA2_BUILD_COMPILER_VERSION}"
+#define ICINGA_VERSION "${ICINGA2_VERSION}"
+#define ICINGA_RC_VERSION "${ICINGA2_RC_VERSION}"
+#cmakedefine01 ICINGA2_INCLUDE_PACKAGE_INFO
+#define ICINGA_PACKAGE_VERSION "${ICINGA2_PACKAGE_VERSION}"
+#define ICINGA_PACKAGE_REVISION "${ICINGA2_PACKAGE_REVISION}"
+#define ICINGA_PACKAGE_VENDOR "${ICINGA2_PACKAGE_VENDOR}"
+
// Deprecated options?
#define ICINGA_PKGDATADIR "${ICINGA2_FULL_PKGDATADIR}"
#define ICINGA_PREFIX "${CMAKE_INSTALL_PREFIX}"
diff --git a/doc/21-development.md b/doc/21-development.md
index 143319b34f4..e87c01bdfc4 100644
--- a/doc/21-development.md
+++ b/doc/21-development.md
@@ -2391,12 +2391,11 @@ for implementation details.
#### Version detection
-CMake determines the Icinga 2 version number using `git describe` if the
-source directory is contained in a Git repository. Otherwise the version number
-is extracted from the `ICINGA2_VERSION` file. This behavior can be
-overridden by creating a file called `icinga-version.h.force` in the source
-directory. Alternatively the `-DICINGA2_GIT_VERSION_INFO=OFF` option for CMake
-can be used to disable the usage of `git describe`.
+CMake determines the Icinga 2 version number using `git describe` if the source directory is contained
+in a Git repository or if the source directory has been extracted from an archive built with `git-archive`.
+Otherwise the version number is specified in the `ICINGA2_VERSION` variable in the main `CMakeLists.txt`
+file. The `-DICINGA2_GIT_VERSION_INFO=OFF` option for CMake can be used to disable the usage of
+`git describe`.
### Building RPMs
diff --git a/icinga-app/icinga.rc b/icinga-app/icinga.rc
index ac4836e42c3..5904ceec616 100644
--- a/icinga-app/icinga.rc
+++ b/icinga-app/icinga.rc
@@ -1,5 +1,5 @@
#include
-#include "icinga-version.h"
+#include "config.h"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
@@ -18,12 +18,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Icinga GmbH"
VALUE "FileDescription", "Icinga 2"
- VALUE "FileVersion", ICINGA2_VERSION
+ VALUE "FileVersion", ICINGA_RC_VERSION
VALUE "InternalName", "icinga2.exe"
VALUE "LegalCopyright", "© Icinga GmbH"
VALUE "OriginalFilename", "icinga2.exe"
VALUE "ProductName", "Icinga 2"
- VALUE "ProductVersion", ICINGA2_VERSION
+ VALUE "ProductVersion", ICINGA_RC_VERSION
END
END
diff --git a/icinga-archive-version.cmake b/icinga-archive-version.cmake
new file mode 100644
index 00000000000..b96367eca39
--- /dev/null
+++ b/icinga-archive-version.cmake
@@ -0,0 +1 @@
+set(ICINGA2_VERSION "$Format:%(describe)$")
diff --git a/icinga-spec-version.h.cmake b/icinga-spec-version.h.cmake
deleted file mode 100644
index 60a77bf6047..00000000000
--- a/icinga-spec-version.h.cmake
+++ /dev/null
@@ -1 +0,0 @@
-#define SPEC_VERSION "${SPEC_VERSION}"
diff --git a/icinga-version.h.cmake b/icinga-version.h.cmake
deleted file mode 100644
index 44acd8c9e36..00000000000
--- a/icinga-version.h.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-#define VERSION "${GIT_VERSION}"
-#define ICINGA2_VERSION "${ICINGA2_VERSION}"
diff --git a/lib/base/application-version.cpp b/lib/base/application-version.cpp
index d17775b7339..1bb2d044bb8 100644
--- a/lib/base/application-version.cpp
+++ b/lib/base/application-version.cpp
@@ -1,17 +1,31 @@
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
#include "base/application.hpp"
-#include "icinga-version.h"
-#include "icinga-spec-version.h"
+#include "config.h"
using namespace icinga;
String Application::GetAppVersion()
{
- return VERSION;
+ return ICINGA_VERSION;
}
-String Application::GetAppSpecVersion()
+bool Application::GetAppIncludePackageInfo()
{
- return SPEC_VERSION;
+ return ICINGA2_INCLUDE_PACKAGE_INFO;
+}
+
+String Application::GetAppPackageVersion()
+{
+ return ICINGA_PACKAGE_VERSION;
+}
+
+String Application::GetAppPackageRevision()
+{
+ return ICINGA_PACKAGE_REVISION;
+}
+
+String Application::GetAppPackageVendor()
+{
+ return ICINGA_PACKAGE_VENDOR;
}
diff --git a/lib/base/application.cpp b/lib/base/application.cpp
index e450b330006..edf054cdddf 100644
--- a/lib/base/application.cpp
+++ b/lib/base/application.cpp
@@ -570,6 +570,12 @@ void Application::DisplayInfoMessage(std::ostream& os, bool skipVersion)
<< " Build host: " << systemNS->Get("BuildHostName") << "\n"
<< " OpenSSL version: " << GetOpenSSLVersion() << "\n";
+ if (Application::GetAppIncludePackageInfo()) {
+ os << "\nPackage information:\n"
+ << " Version: " << Application::GetAppPackageVersion() << "-" << Application::GetAppPackageRevision() << "\n"
+ << " Vendor: " << Application::GetAppPackageVendor() << "\n";
+ }
+
os << "\nApplication information:\n"
<< "\nGeneral paths:\n"
<< " Config directory: " << Configuration::ConfigDir << "\n"
diff --git a/lib/base/application.hpp b/lib/base/application.hpp
index f45c8bdd74a..8614414614e 100644
--- a/lib/base/application.hpp
+++ b/lib/base/application.hpp
@@ -91,7 +91,11 @@ class Application : public ObjectImpl {
static ThreadPool& GetTP();
static String GetAppVersion();
- static String GetAppSpecVersion();
+
+ static bool GetAppIncludePackageInfo();
+ static String GetAppPackageVersion();
+ static String GetAppPackageRevision();
+ static String GetAppPackageVendor();
static String GetAppEnvironment();
static void SetAppEnvironment(const String& name);
diff --git a/lib/base/library.cpp b/lib/base/library.cpp
index 541ed74ad10..db8944a47b4 100644
--- a/lib/base/library.cpp
+++ b/lib/base/library.cpp
@@ -19,9 +19,9 @@ Library::Library(const String& name)
#if defined(_WIN32)
path = name + ".dll";
#elif defined(__APPLE__)
- path = "lib" + name + "." + Application::GetAppSpecVersion() + ".dylib";
+ path = "lib" + name + "." + Application::GetAppPackageVersion() + ".dylib";
#else /* __APPLE__ */
- path = "lib" + name + ".so." + Application::GetAppSpecVersion();
+ path = "lib" + name + ".so." + Application::GetAppPackageVersion();
#endif /* _WIN32 */
Log(LogNotice, "Library")
diff --git a/lib/mysql_shim/CMakeLists.txt b/lib/mysql_shim/CMakeLists.txt
index 8b982393a6d..1d0fc02949f 100644
--- a/lib/mysql_shim/CMakeLists.txt
+++ b/lib/mysql_shim/CMakeLists.txt
@@ -21,7 +21,7 @@ target_link_libraries(mysql_shim ${MYSQL_LIB})
set_target_properties (
mysql_shim PROPERTIES
FOLDER Lib
- VERSION ${SPEC_VERSION}
+ VERSION ${ICINGA2_PACKAGE_VERSION}
)
install(
diff --git a/lib/pgsql_shim/CMakeLists.txt b/lib/pgsql_shim/CMakeLists.txt
index 06395ac99cd..a5971ec6591 100644
--- a/lib/pgsql_shim/CMakeLists.txt
+++ b/lib/pgsql_shim/CMakeLists.txt
@@ -22,7 +22,7 @@ target_link_libraries(pgsql_shim ${PostgreSQL_LIBRARIES})
set_target_properties (
pgsql_shim PROPERTIES
FOLDER Lib
- VERSION ${SPEC_VERSION}
+ VERSION ${ICINGA2_PACKAGE_VERSION}
)
install(
diff --git a/plugins/check_nscp_api.cpp b/plugins/check_nscp_api.cpp
index 1a4f5571ec4..66d8f3e1e1c 100644
--- a/plugins/check_nscp_api.cpp
+++ b/plugins/check_nscp_api.cpp
@@ -1,7 +1,5 @@
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
-#include "icinga-version.h" /* include VERSION */
-
// ensure to include base first
#include "base/i2-base.hpp"
#include "base/application.hpp"
@@ -365,7 +363,7 @@ static Dictionary::Ptr FetchData(const String& host, const String& port, const S
http::request request (http::verb::get, std::string(url->Format(true)), 10);
- request.set(http::field::user_agent, "Icinga/check_nscp_api/" + String(VERSION));
+ request.set(http::field::user_agent, "Icinga/check_nscp_api/" + Application::GetAppVersion());
request.set(http::field::host, host + ":" + port);
request.set(http::field::accept, "application/json");
@@ -451,12 +449,12 @@ int main(int argc, char **argv)
vm);
if (vm.count("version")) {
- std::cout << "Version: " << VERSION << '\n';
+ std::cout << "Version: " << Application::GetAppVersion() << '\n';
Application::Exit(0);
}
if (vm.count("help")) {
- std::cout << argv[0] << " Help\n\tVersion: " << VERSION << '\n';
+ std::cout << argv[0] << " Help\n\tVersion: " << Application::GetAppVersion() << '\n';
std::cout << "check_nscp_api is a program used to query the NSClient++ API.\n";
std::cout << desc;
std::cout << "For detailed information on possible queries and their arguments refer to the NSClient++ documentation.\n";