From 5b872da1aee140aa7b8d6d65463151aed09974b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20V=C3=A1vra?= Date: Thu, 17 Oct 2024 16:43:24 +0200 Subject: [PATCH] feat: Implement get_package_version in hosts/base.py Find package version and parse it to major, minor, patch, pre-release, update release. --- sssd_test_framework/hosts/base.py | 48 +++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/sssd_test_framework/hosts/base.py b/sssd_test_framework/hosts/base.py index efdc947..01bb5eb 100644 --- a/sssd_test_framework/hosts/base.py +++ b/sssd_test_framework/hosts/base.py @@ -3,6 +3,7 @@ from __future__ import annotations import csv +import re from typing import Any import ldap @@ -264,3 +265,50 @@ def distro_minor(self) -> int: if not self._os_release: self._distro_information() return self._distro_minor + + def get_package_version(self, package: str = "sssd", raise_on_error: bool = True) -> dict: + """ + Parse package version and return it as a dictionary with: + major, minor, patch, prerelease, update, release + :param package: package name + :param raise_on_error: raise exeption when package is missing + :return: version dictionary + :rtype: dict + :raises OSError: If package is missing or version could not be parsed. + """ + vers = { + "major": 0, + "minor": 0, + "patch": 0, + "prerelease": "", + "update": 0, + "release": "", + } + rpm = self.conn.run("test -f /usr/bin/rpm", raise_on_error=False) + dpkg = self.conn.run("test -f /usr/bin/dpkg-query", raise_on_error=False) + if rpm.rc == 0: + ver = self.conn.run(f'rpm -q {package} --queryformat "%{{VERSION}}-%{{RELEASE}}"').stdout + elif dpkg.rc != 0: + ver = self.conn.run(f"dpkg-query -f '${{Version}}' -W {package}").stdout + else: + if raise_on_error: + raise OSError(f"Package {package} not found!") + return vers + + v_match = re.match( + r"([0-9]+)(?:\.)?([0-9]+)?(?:\.)?([0-9]+)?(?:~)?([a-z0-9]+)?[\.-]?([0-9]+)?(?:\.)?(.*)?", + ver, + re.IGNORECASE, + ) + + if v_match is None: + if raise_on_error: + raise OSError(f"Package {package} version could not be parsed!") + return vers + vers["major"] = int(v_match.group(1)) + vers["minor"] = int(v_match.group(2)) if v_match.group(2) else 0 + vers["patch"] = int(v_match.group(3)) if v_match.group(3) else 0 + vers["prerelease"] = v_match.group(4) if v_match.group(4) else "" + vers["update"] = int(v_match.group(5)) if v_match.group(5) else 0 + vers["release"] = v_match.group(6) if v_match.group(6) else "" + return vers