From f4d71b664d0febc4ee766ac2324008d28cb42266 Mon Sep 17 00:00:00 2001 From: "a.berezin" Date: Fri, 7 Jun 2024 17:03:39 +0300 Subject: [PATCH] [#244] Update versions check Signed-off-by: a.berezin --- src/frostfs_testlib/utils/version_utils.py | 83 ++++++++-------------- 1 file changed, 29 insertions(+), 54 deletions(-) diff --git a/src/frostfs_testlib/utils/version_utils.py b/src/frostfs_testlib/utils/version_utils.py index f1b7e37..7fcc9de 100644 --- a/src/frostfs_testlib/utils/version_utils.py +++ b/src/frostfs_testlib/utils/version_utils.py @@ -1,5 +1,6 @@ import logging import re +from functools import lru_cache from frostfs_testlib import reporter from frostfs_testlib.cli import FrostfsAdm, FrostfsCli @@ -36,78 +37,52 @@ def get_local_binaries_versions(shell: Shell) -> dict[str, str]: return versions +@reporter.step("Collect binaries versions from host") def parallel_binary_verions(host: Host) -> dict[str, str]: versions_by_host = {} - binary_path_by_name = {} # Maps binary name to executable path - for service_config in host.config.services: - exec_path = service_config.attributes.get("exec_path") - requires_check = service_config.attributes.get("requires_version_check", "true") - if exec_path: - binary_path_by_name[service_config.name] = { - "exec_path": exec_path, - "check": requires_check.lower() == "true", + binary_path_by_name = { + **{ + svc.name[:-3]: { + "exec_path": svc.attributes.get("exec_path"), + "param": svc.attributes.get("custom_version_parameter", "--version"), } - for cli_config in host.config.clis: - requires_check = cli_config.attributes.get("requires_version_check", "true") - binary_path_by_name[cli_config.name] = { - "exec_path": cli_config.exec_path, - "check": requires_check.lower() == "true", - } + for svc in host.config.services + if svc.attributes.get("exec_path") and svc.attributes.get("requires_version_check", "true") == "true" + }, + **{ + cli.name: {"exec_path": cli.exec_path, "param": cli.attributes.get("custom_version_parameter", "--version")} + for cli in host.config.clis + if cli.attributes.get("requires_version_check", "true") == "true" + }, + } shell = host.get_shell() versions_at_host = {} for binary_name, binary in binary_path_by_name.items(): + binary_path = binary["exec_path"] try: - binary_path = binary["exec_path"] - result = shell.exec(f"{binary_path} --version") - versions_at_host[binary_name] = {"version": _parse_version(result.stdout), "check": binary["check"]} + result = shell.exec(f"{binary_path} {binary['param']}") + version = _parse_version(result.stdout) or _parse_version(result.stderr) or "Unknown" + versions_at_host[binary_name] = version except Exception as exc: logger.error(f"Cannot get version for {binary_path} because of\n{exc}") - versions_at_host[binary_name] = {"version": "Unknown", "check": binary["check"]} + versions_at_host[binary_name] = "Unknown" versions_by_host[host.config.address] = versions_at_host return versions_by_host -@reporter.step("Get remote binaries versions") -def get_remote_binaries_versions(hosting: Hosting) -> dict[str, str]: - versions_by_host = {} - future_binary_verions = parallel(parallel_binary_verions, parallel_items=hosting.hosts) +@lru_cache +def get_remote_binaries_versions(hosting: Hosting) -> dict[str, dict[str, str]]: + versions_by_host: dict[str, dict[str, str]] = {} + + with reporter.step("Get remote binaries versions"): + future_binary_verions = parallel(parallel_binary_verions, parallel_items=hosting.hosts) + for future in future_binary_verions: versions_by_host.update(future.result()) - # Consolidate versions across all hosts - cheak_versions = {} - exсeptions = [] - exception = set() - previous_host = None - versions = {} - captured_version = None - for host, binary_versions in versions_by_host.items(): - for name, binary in binary_versions.items(): - version = binary["version"] - if not cheak_versions.get(f"{name[:-2]}", None): - captured_version = cheak_versions.get(f"{name[:-2]}", {}).get(host, {}).get(captured_version) - cheak_versions[f"{name[:-2]}"] = {host: {version: name}} - else: - captured_version = list(cheak_versions.get(f"{name[:-2]}", {}).get(previous_host).keys())[0] - cheak_versions[f"{name[:-2]}"].update({host: {version: name}}) - - if captured_version and captured_version != version: - exception.add(name[:-2]) - - versions[name] = {"version": version, "check": binary["check"]} - previous_host = host - logger.info( - "Remote binaries versions:\n" + "\n".join([f"{key} ver: {value['version']}" for key, value in versions.items()]) - ) - if exception: - for i in exception: - for host in versions_by_host.keys(): - for version, name in cheak_versions.get(i).get(host).items(): - exсeptions.append(f"Binary {name} has inconsistent version {version} on host {host}") - exсeptions.append("\n") - return versions, exсeptions + return versions_by_host def _parse_version(version_output: str) -> str: