From 28a22f68fb3eb8b44ae28aa806584f4da68244e3 Mon Sep 17 00:00:00 2001 From: Aleksei Burlakov Date: Thu, 1 Aug 2024 12:01:15 +0200 Subject: [PATCH] Dev: scripts/health/collect: use ansible to get sysinfo --- crmsh/utils.py | 24 +++++++++++++++++++++++ scripts/health/collect.py | 26 +++++++++++++++++++++++-- utils/crm_rpmcheck.py | 40 +++++++++++++-------------------------- 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/crmsh/utils.py b/crmsh/utils.py index b91abbc712..256ddc6d95 100644 --- a/crmsh/utils.py +++ b/crmsh/utils.py @@ -26,6 +26,7 @@ import gzip import bz2 import lzma +import json from pathlib import Path from contextlib import contextmanager, closing from stat import S_ISBLK @@ -3107,4 +3108,27 @@ def time_value_with_unit(time_value): Check if the time value contains unit """ return re.search(r'^\d+[a-z]+$', time_value) is not None + + +def ansible_installed(): + return shutil.which('ansible') + + +def ansible_facts(module_name) -> dict: + proc = subprocess.run(['ansible', '-m', module_name, 'localhost'] + , capture_output=True, text=True) + out = proc.stdout + # output format 'localhost | SUCCESS => { json...' + bracket_pos = out.find('{') + if bracket_pos == -1: + logger.error("Parsing ansible output.") + return {} + is_ok = out[:bracket_pos].find('SUCCESS =>') + if is_ok == -1: + logger.error("Failure calling ansible module.") + return {} + # get the json part + out = out[bracket_pos:] + json_tree = json.loads(out) + return json_tree['ansible_facts'] # vim:ts=4:sw=4:et: diff --git a/scripts/health/collect.py b/scripts/health/collect.py index 95b5e4ac9b..5e2629a616 100755 --- a/scripts/health/collect.py +++ b/scripts/health/collect.py @@ -10,6 +10,7 @@ import crmsh.log crmsh.log.setup_logging() from crmsh.report import utils +import crmsh.utils data = crm_script.get_input() @@ -32,6 +33,27 @@ def get_user(): def sys_info(): + with open('/proc/uptime') as f: + uptime = f.read().split() + + if crmsh.utils.ansible_installed(): + facts = crmsh.utils.ansible_facts('setup') + + return {'system': facts.get("ansible_system"), + 'node': facts.get("ansible_hostname"), + 'release': facts.get("ansible_kernel"), + 'version': facts.get("ansible_kernel_version"), + 'machine': facts.get("ansible_machine"), + 'processor': facts.get("ansible_architecture"), + 'distname': facts.get("ansible_distribution"), + 'user': facts.get("ansible_user_id"), + 'hostname': facts.get("ansible_nodename"), + 'uptime': facts.get("ansible_uptime_seconds"), + 'idletime': uptime[1], # :( not in ansible setup module + 'loadavg': facts.get("ansible_loadavg").get("15m") # 15 minute average + } + + # if ansible is not installed, do it like before sysname, nodename, release, version, machine = os.uname() # The first three columns measure CPU and IO utilization of the # last one, five, and 15 minute periods. The fourth column shows @@ -41,8 +63,8 @@ def sys_info(): distname = utils.get_distro_info() hostname = os.uname()[1] - uptime = open('/proc/uptime').read().split() - loadavg = open('/proc/loadavg').read().split() + with open('/proc/loadavg') as f: + loadavg = f.read().split() return {'system': system, 'node': node, diff --git a/utils/crm_rpmcheck.py b/utils/crm_rpmcheck.py index 18da3b3dcf..ea625de193 100755 --- a/utils/crm_rpmcheck.py +++ b/utils/crm_rpmcheck.py @@ -7,6 +7,7 @@ import json import subprocess import shutil +from crmsh import utils def run(cmd): proc = subprocess.Popen(cmd, @@ -23,10 +24,8 @@ def package_data(pkg): """ Gathers version and release information about a package. """ - if shutil.which('ansible'): - rc, data = ansible_package_data(pkg) - if rc == 0: - return data + if utils.ansible_installed(): + return ansible_package_data(pkg) if shutil.which('rpm'): return rpm_package_data(pkg) @@ -36,36 +35,23 @@ def package_data(pkg): return {'name': pkg, 'error': "unknown package manager"} + _packages = None -def ansible_package_data(pkg) -> tuple[int, dict]: +def ansible_package_data(pkg) -> dict: """ Gathers version and release information about a package. Using ansible. """ + # if _packages is None, then get it global _packages if not _packages: - # if _packages is None, then get it - rc, out, err = run(['ansible', '-m', 'package_facts', 'localhost']) - if rc == -1: - return -1, {} - # output format 'localhost | SUCCESS => { json...' - bracket_pos = out.find('{') - if bracket_pos == -1: - return -1, {} - is_ok = out[:bracket_pos].find('SUCCESS =>') - if is_ok == -1: - return -1, {} - - # get the json part - out = out[bracket_pos:] - json_tree = json.loads(out) - # get _packages - _packages = json_tree['ansible_facts']['packages'] - - if pkg not in _packages: - return 0, {'name': pkg, 'error': "package not installed"} - else: - return 0, _packages[pkg][0] + facts = utils.ansible_facts('package_facts') + _packages = facts.get('packages') + + if _packages and pkg in _packages: + return _packages[pkg][0] + + return {'name': pkg, 'error': "package not installed"} def rpm_package_data(pkg):