From c73df2bb04147df075199abc79bc69a2c7a1cc22 Mon Sep 17 00:00:00 2001 From: xudan Date: Mon, 30 Oct 2017 04:44:26 -0400 Subject: Get hardware info of SUT Hardware info: Use ansible to get all hardware info from all nodes. JIRA: DOVETAIL-540 Change-Id: I6a2dde1b2ebae2af8f702008c23110ebe63cc06f Signed-off-by: xudan --- dovetail/run.py | 2 + dovetail/userconfig/ansible.cfg | 2 + dovetail/utils/dovetail_utils.py | 82 ++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 + 4 files changed, 88 insertions(+) create mode 100644 dovetail/userconfig/ansible.cfg diff --git a/dovetail/run.py b/dovetail/run.py index 0306efe4..b7c78975 100755 --- a/dovetail/run.py +++ b/dovetail/run.py @@ -280,6 +280,8 @@ def main(*args, **kwargs): else: dt_cfg.dovetail_config['offline'] = False + dt_utils.get_hardware_info(logger) + origin_testarea = kwargs['testarea'] testsuite_validation = False if kwargs['testsuite'] in dt_cfg.dovetail_config['testsuite_supported']: diff --git a/dovetail/userconfig/ansible.cfg b/dovetail/userconfig/ansible.cfg new file mode 100644 index 00000000..14c80651 --- /dev/null +++ b/dovetail/userconfig/ansible.cfg @@ -0,0 +1,2 @@ +[defaults] +host_key_checking = False diff --git a/dovetail/utils/dovetail_utils.py b/dovetail/utils/dovetail_utils.py index fc007e51..75f7356b 100644 --- a/dovetail/utils/dovetail_utils.py +++ b/dovetail/utils/dovetail_utils.py @@ -18,6 +18,9 @@ import json import urllib2 from datetime import datetime from distutils.version import LooseVersion +import yaml + +from dovetail_config import DovetailConfig as dt_cfg def exec_log(verbose, logger, msg, level, flush=False): @@ -215,3 +218,82 @@ def add_hosts_info(hosts_info): hosts_file = '/etc/hosts' with open(hosts_file, 'a') as f: f.write("{}\n".format(hosts_info)) + + +def get_hardware_info(logger=None): + pod_file = os.path.join(dt_cfg.dovetail_config['config_dir'], + dt_cfg.dovetail_config['pod_file']) + logger.info("Get hardware info of all nodes list in file {} ..." + .format(pod_file)) + result_dir = dt_cfg.dovetail_config['result_dir'] + info_file_path = os.path.join(result_dir, 'sut_hardware_info') + all_info_file = os.path.join(result_dir, 'all_hosts_info.json') + inventory_file = os.path.join(result_dir, 'inventory.ini') + if not get_inventory_file(pod_file, inventory_file, logger): + logger.error("Failed to get SUT hardware info.") + return None + ret, msg = exec_cmd("cd /home/opnfv/dovetail/dovetail/userconfig " + "&& ansible all -m setup -i {} --tree {}" + .format(inventory_file, info_file_path), verbose=False) + if not os.path.exists(info_file_path) or ret != 0: + logger.error("Failed to get SUT hardware info.") + return None + if not combine_files(info_file_path, all_info_file, logger): + logger.error("Failed to get all hardware info.") + return None + logger.info("Hardware info of all nodes are stored in file {}." + .format(all_info_file)) + return all_info_file + + +def get_inventory_file(pod_file, inventory_file, logger=None): + if not os.path.isfile(pod_file): + logger.error("File {} doesn't exist.".format(pod_file)) + return False + try: + with open(pod_file, 'r') as f, open(inventory_file, 'w') as out_f: + pod_info = yaml.safe_load(f) + for host in pod_info['nodes']: + host_info = ('{} ansible_host={} ansible_user={}' + .format(host['name'], host['ip'], host['user'])) + if 'password' in host.keys(): + host_info += (' ansible_ssh_pass={}\n' + .format(host['password'])) + elif 'key_filename' in host.keys(): + key = os.path.join(dt_cfg.dovetail_config['config_dir'], + 'id_rsa') + host_info += (' ansible_ssh_private_key_file={}\n' + .format(key)) + else: + logger.error('No password or key_filename in file {}.' + .format(pod_file)) + return False + out_f.write(host_info) + logger.debug("Ansible inventory file is {}.".format(inventory_file)) + return True + except KeyError as e: + logger.exception("KeyError {}.".format(e)) + return False + except Exception: + logger.exception("Failed to read file {}.".format(pod_file)) + return False + + +def combine_files(file_path, result_file, logger=None): + all_info = {} + info_files = os.listdir(file_path) + for info_file in info_files: + try: + absolute_file_path = os.path.join(file_path, info_file) + with open(absolute_file_path, 'r') as f: + all_info[info_file] = json.load(f) + except Exception: + logger.error("Failed to read file {}.".format(absolute_file_path)) + return None + try: + with open(result_file, 'w') as f: + f.write(json.dumps(all_info)) + except Exception: + logger.exception("Failed to write file {}.".format(result_file)) + return None + return result_file diff --git a/requirements.txt b/requirements.txt index 0aaa5086..9eaaf3c3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,7 @@ +ansible==2.2.0 click==6.6 Jinja2==2.8 +paramiko==1.18.0 pbr==2.0.0 pytz==2016.7 PyYAML==3.11 -- cgit 1.2.3-korg