From f4d388ea508ba00771e43a219ac64e0d430b73bd Mon Sep 17 00:00:00 2001 From: Tim Rozet Date: Sun, 25 Jun 2017 21:25:36 -0400 Subject: Migrates Apex to Python Removes all bash libraries and converts almost all of the code to a mixture of Python and Ansible. utils.sh and clean.sh still exist. clean.sh will be migrated fully to clean.py in another patch. The Apex Python package is now built into the opnfv-apex-common RPM. To install locally do 'pip3 install .'. To deploy: opnfv-deploy -d -n --image-dir /root/apex/.build -v --debug Non-python files (THT yaml, settings files, ansible playbooks) are all installed into /usr/share/opnfv-apex/. The RPM will copy settings files into /etc/opnfv-apex/. JIRA: APEX-317 Change-Id: I3232f0329bcd13bce5a28da6a8c9c84d0b048024 Signed-off-by: Tim Rozet --- apex/common/utils.py | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 apex/common/utils.py (limited to 'apex/common/utils.py') diff --git a/apex/common/utils.py b/apex/common/utils.py new file mode 100644 index 00000000..848f2644 --- /dev/null +++ b/apex/common/utils.py @@ -0,0 +1,107 @@ +############################################################################## +# Copyright (c) 2016 Tim Rozet (trozet@redhat.com) and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +import json +import logging +import os +import pprint +import subprocess +import yaml + + +def str2bool(var): + if isinstance(var, bool): + return var + else: + return var.lower() in ("true", "yes") + + +def parse_yaml(yaml_file): + with open(yaml_file) as f: + parsed_dict = yaml.safe_load(f) + return parsed_dict + + +def dump_yaml(data, file): + """ + Dumps data to a file as yaml + :param data: yaml to be written to file + :param file: filename to write to + :return: + """ + logging.debug("Writing file {} with " + "yaml data:\n{}".format(file, yaml.safe_dump(data))) + with open(file, "w") as fh: + yaml.safe_dump(data, fh, default_flow_style=False) + + +def dict_objects_to_str(dictionary): + if isinstance(dictionary, list): + tmp_list = [] + for element in dictionary: + if isinstance(element, dict): + tmp_list.append(dict_objects_to_str(element)) + else: + tmp_list.append(str(element)) + return tmp_list + elif not isinstance(dictionary, dict): + if not isinstance(dictionary, bool): + return str(dictionary) + else: + return dictionary + return dict((k, dict_objects_to_str(v)) for + k, v in dictionary.items()) + + +def run_ansible(ansible_vars, playbook, host='localhost', user='root', + tmp_dir=None, dry_run=False): + """ + Executes ansible playbook and checks for errors + :param ansible_vars: dictionary of variables to inject into ansible run + :param playbook: playbook to execute + :param tmp_dir: temp directory to store ansible command + :param dry_run: Do not actually apply changes + :return: None + """ + logging.info("Executing ansible playbook: {}".format(playbook)) + inv_host = "{},".format(host) + if host == 'localhost': + conn_type = 'local' + else: + conn_type = 'smart' + ansible_command = ['ansible-playbook', '--become', '-i', inv_host, + '-u', user, '-c', conn_type, playbook, '-vvv'] + if dry_run: + ansible_command.append('--check') + + if isinstance(ansible_vars, dict) and ansible_vars: + logging.debug("Ansible variables to be set:\n{}".format( + pprint.pformat(ansible_vars))) + ansible_command.append('--extra-vars') + ansible_command.append(json.dumps(ansible_vars)) + if tmp_dir: + ansible_tmp = os.path.join(tmp_dir, + os.path.basename(playbook) + '.rerun') + # FIXME(trozet): extra vars are printed without single quotes + # so a dev has to add them manually to the command to rerun + # the playbook. Need to test if we can just add the single quotes + # to the json dumps to the ansible command and see if that works + with open(ansible_tmp, 'w') as fh: + fh.write("ANSIBLE_HOST_KEY_CHECKING=FALSE {}".format( + ' '.join(ansible_command))) + try: + my_env = os.environ.copy() + my_env['ANSIBLE_HOST_KEY_CHECKING'] = 'False' + logging.info("Executing playbook...this may take some time") + logging.debug(subprocess.check_output(ansible_command, env=my_env, + stderr=subprocess.STDOUT).decode('utf-8')) + except subprocess.CalledProcessError as e: + logging.error("Error executing ansible: {}".format( + pprint.pformat(e.output.decode('utf-8')))) + raise -- cgit 1.2.3-korg