IcingaHealth: Fix version comparison

There are multiple possible outputs for an Icinga DB version. The
package version contain the git tag, with a leading "v". The development
version mimics git-describe(1), including a commit hash separated by a
dash after the semantic version.

The current version comparison uses PHP's builtin version_compare().

This results in leading "v"s to return invalid results. Furthermore, it
treats everything behind the version as an "any string"[^0], which is
smaller than dev, alpha, beta, and so on. Thus, any git-describe(1)
version of Icinga DB 1.4.0 would be considered smaller as 1.4.0.

Fixes #1230.

[^0]: https://www.php.net/manual/en/function.version-compare.php
This commit is contained in:
Alvar Penning 2025-06-20 08:48:43 +02:00 committed by Eric Lippmann
parent 4296d0d385
commit 3e0bd96ec6
2 changed files with 28 additions and 2 deletions

View file

@ -16,6 +16,24 @@ class IcingaHealth extends HealthHook
public const REQUIRED_ICINGADB_VERSION = '1.4.0';
/**
* normalizeVersion extracts a version string from Icinga DB's reported
* version comparable with REQUIRED_ICINGADB_VERSION via version_compare.
*
* @param string $version Icinga DB version string to normalize.
*
* @return string Normalized Icinga DB version string.
*/
public static function normalizeVersion(string $version): string
{
// Ignore leading "v" when the git tag is used, e.g., "v1.4.0".
$version = ltrim($version, 'v');
// Ignore everything after "-" used by git describe, e.g., "1.4.0-g...".
$version = explode('-', $version, 2)[0];
return $version;
}
/** @var Instance */
protected $instance;
@ -47,7 +65,11 @@ class IcingaHealth extends HealthHook
));
} elseif (
! isset($instance->icingadb_version)
|| version_compare($instance->icingadb_version, self::REQUIRED_ICINGADB_VERSION, '<')
|| version_compare(
self::normalizeVersion($instance->icingadb_version),
self::REQUIRED_ICINGADB_VERSION,
'<'
)
) {
$this->setState(self::STATE_CRITICAL);
$this->setMessage(sprintf(

View file

@ -26,7 +26,11 @@ class Health extends BaseHtmlElement
{
if (
! isset($this->data->icingadb_version)
|| version_compare($this->data->icingadb_version, IcingaHealth::REQUIRED_ICINGADB_VERSION, '<')
|| version_compare(
IcingaHealth::normalizeVersion($this->data->icingadb_version),
IcingaHealth::REQUIRED_ICINGADB_VERSION,
'<'
)
) {
$this->addHtml(Html::tag('div', ['class' => 'icinga-health down'], [
sprintf(