forked from TrueCloudLab/frostfs-testlib
[#172] parallel get remote binaries versions
This commit is contained in:
parent
0d7a15877c
commit
6caa77dedf
1 changed files with 61 additions and 39 deletions
|
@ -2,10 +2,11 @@ import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from frostfs_testlib.cli import FrostfsAdm, FrostfsCli
|
from frostfs_testlib.cli import FrostfsAdm, FrostfsCli
|
||||||
from frostfs_testlib.hosting import Hosting
|
from frostfs_testlib.hosting import Host, Hosting
|
||||||
from frostfs_testlib.resources.cli import FROSTFS_ADM_EXEC, FROSTFS_AUTHMATE_EXEC, FROSTFS_CLI_EXEC, NEOGO_EXECUTABLE
|
from frostfs_testlib.resources.cli import FROSTFS_ADM_EXEC, FROSTFS_AUTHMATE_EXEC, FROSTFS_CLI_EXEC, NEOGO_EXECUTABLE
|
||||||
from frostfs_testlib.resources.common import DEFAULT_WALLET_CONFIG
|
from frostfs_testlib.resources.common import DEFAULT_WALLET_CONFIG
|
||||||
from frostfs_testlib.shell import Shell
|
from frostfs_testlib.shell import Shell
|
||||||
|
from frostfs_testlib.testing.parallel import parallel
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
|
||||||
|
@ -33,53 +34,74 @@ def get_local_binaries_versions(shell: Shell) -> dict[str, str]:
|
||||||
return versions
|
return versions
|
||||||
|
|
||||||
|
|
||||||
|
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",
|
||||||
|
}
|
||||||
|
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",
|
||||||
|
}
|
||||||
|
|
||||||
|
shell = host.get_shell()
|
||||||
|
versions_at_host = {}
|
||||||
|
for binary_name, binary in binary_path_by_name.items():
|
||||||
|
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"]}
|
||||||
|
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_by_host[host.config.address] = versions_at_host
|
||||||
|
return versions_by_host
|
||||||
|
|
||||||
|
|
||||||
def get_remote_binaries_versions(hosting: Hosting) -> dict[str, str]:
|
def get_remote_binaries_versions(hosting: Hosting) -> dict[str, str]:
|
||||||
versions_by_host = {}
|
versions_by_host = {}
|
||||||
for host in hosting.hosts:
|
future_binary_verions = parallel(parallel_binary_verions, parallel_items=hosting.hosts)
|
||||||
binary_path_by_name = {} # Maps binary name to executable path
|
for future in future_binary_verions:
|
||||||
for service_config in host.config.services:
|
versions_by_host.update(future.result())
|
||||||
exec_path = service_config.attributes.get("exec_path")
|
|
||||||
requires_check = service_config.attributes.get("requires_version_check", "true")
|
|
||||||
version_parameter = service_config.attributes.get("custom_version_parameter", "--version")
|
|
||||||
if exec_path:
|
|
||||||
binary_path_by_name[service_config.name] = {
|
|
||||||
"exec_path": exec_path,
|
|
||||||
"check": requires_check.lower() == "true",
|
|
||||||
"version_parameter": version_parameter,
|
|
||||||
}
|
|
||||||
for cli_config in host.config.clis:
|
|
||||||
requires_check = cli_config.attributes.get("requires_version_check", "true")
|
|
||||||
version_parameter = service_config.attributes.get("custom_version_parameter", "--version")
|
|
||||||
binary_path_by_name[cli_config.name] = {
|
|
||||||
"exec_path": cli_config.exec_path,
|
|
||||||
"check": requires_check.lower() == "true",
|
|
||||||
"version_parameter": version_parameter,
|
|
||||||
}
|
|
||||||
|
|
||||||
shell = host.get_shell()
|
|
||||||
versions_at_host = {}
|
|
||||||
for binary_name, binary in binary_path_by_name.items():
|
|
||||||
try:
|
|
||||||
binary_path = binary["exec_path"]
|
|
||||||
result = shell.exec(f"{binary_path} {binary['version_parameter']}")
|
|
||||||
versions_at_host[binary_name] = {"version": _parse_version(result.stdout), "check": binary["check"]}
|
|
||||||
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_by_host[host.config.address] = versions_at_host
|
|
||||||
|
|
||||||
# Consolidate versions across all hosts
|
# Consolidate versions across all hosts
|
||||||
|
cheak_versions = {}
|
||||||
|
exсeptions = []
|
||||||
|
exception = set()
|
||||||
|
previous_host = None
|
||||||
versions = {}
|
versions = {}
|
||||||
|
captured_version = None
|
||||||
for host, binary_versions in versions_by_host.items():
|
for host, binary_versions in versions_by_host.items():
|
||||||
for name, binary in binary_versions.items():
|
for name, binary in binary_versions.items():
|
||||||
captured_version = versions.get(name, {}).get("version")
|
|
||||||
version = binary["version"]
|
version = binary["version"]
|
||||||
if captured_version:
|
if not cheak_versions.get(f'{name[:-2]}', None):
|
||||||
assert captured_version == version, f"Binary {name} has inconsistent version on host {host}"
|
captured_version = cheak_versions.get(f'{name[:-2]}',{}).get(host, {}).get(captured_version)
|
||||||
|
cheak_versions[f'{name[:-2]}'] = {host: {version: name}}
|
||||||
else:
|
else:
|
||||||
versions[name] = {"version": version, "check": binary["check"]}
|
captured_version = list(cheak_versions.get(f'{name[:-2]}',{}).get(previous_host).keys())[0]
|
||||||
return versions
|
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
|
||||||
|
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:
|
||||||
version = re.search(r"version[:\s]*v?(.+)", version_output, re.IGNORECASE)
|
version = re.search(r"version[:\s]*v?(.+)", version_output, re.IGNORECASE)
|
||||||
|
|
Loading…
Reference in a new issue