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";