Update versions check #244

Merged
abereziny merged 1 commit from abereziny/frostfs-testlib:feature-update-version-checks into support/v0.39 2024-06-11 10:58:43 +00:00

View file

@ -1,5 +1,6 @@
import logging import logging
import re import re
from functools import lru_cache
from frostfs_testlib import reporter from frostfs_testlib import reporter
from frostfs_testlib.cli import FrostfsAdm, FrostfsCli from frostfs_testlib.cli import FrostfsAdm, FrostfsCli
@ -36,78 +37,52 @@ def get_local_binaries_versions(shell: Shell) -> dict[str, str]:
return versions return versions
@reporter.step("Collect binaries versions from host")
def parallel_binary_verions(host: Host) -> dict[str, str]: def parallel_binary_verions(host: Host) -> dict[str, str]:
versions_by_host = {} versions_by_host = {}
binary_path_by_name = {} # Maps binary name to executable path binary_path_by_name = {
for service_config in host.config.services: **{
exec_path = service_config.attributes.get("exec_path") svc.name[:-3]: {
requires_check = service_config.attributes.get("requires_version_check", "true") "exec_path": svc.attributes.get("exec_path"),
if exec_path: "param": svc.attributes.get("custom_version_parameter", "--version"),
binary_path_by_name[service_config.name] = {
"exec_path": exec_path,
"check": requires_check.lower() == "true",
} }
for cli_config in host.config.clis: for svc in host.config.services
requires_check = cli_config.attributes.get("requires_version_check", "true") if svc.attributes.get("exec_path") and svc.attributes.get("requires_version_check", "true") == "true"
binary_path_by_name[cli_config.name] = { },
"exec_path": cli_config.exec_path, **{
"check": requires_check.lower() == "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() shell = host.get_shell()
versions_at_host = {} versions_at_host = {}
for binary_name, binary in binary_path_by_name.items(): for binary_name, binary in binary_path_by_name.items():
binary_path = binary["exec_path"]
try: try:
binary_path = binary["exec_path"] result = shell.exec(f"{binary_path} {binary['param']}")
result = shell.exec(f"{binary_path} --version") version = _parse_version(result.stdout) or _parse_version(result.stderr) or "Unknown"
versions_at_host[binary_name] = {"version": _parse_version(result.stdout), "check": binary["check"]} versions_at_host[binary_name] = version
except Exception as exc: except Exception as exc:
logger.error(f"Cannot get version for {binary_path} because of\n{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 versions_by_host[host.config.address] = versions_at_host
return versions_by_host return versions_by_host
@reporter.step("Get remote binaries versions") @lru_cache
def get_remote_binaries_versions(hosting: Hosting) -> dict[str, str]: def get_remote_binaries_versions(hosting: Hosting) -> dict[str, dict[str, str]]:
versions_by_host = {} versions_by_host: dict[str, dict[str, str]] = {}
future_binary_verions = parallel(parallel_binary_verions, parallel_items=hosting.hosts)
with reporter.step("Get remote binaries versions"):
future_binary_verions = parallel(parallel_binary_verions, parallel_items=hosting.hosts)
for future in future_binary_verions: for future in future_binary_verions:
versions_by_host.update(future.result()) versions_by_host.update(future.result())
# Consolidate versions across all hosts return versions_by_host
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
def _parse_version(version_output: str) -> str: def _parse_version(version_output: str) -> str: