From 31bdde00c9a415e2083fef285f189b31caca32b4 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Thu, 10 Oct 2019 15:08:20 -0400 Subject: [PATCH 1/2] Check the user's ansible.cfg for role/collection paths. There's no other way to add our new paths reliably without breaking things. --- awx/main/tasks.py | 15 ++++++++++++--- awx/main/utils/ansible.py | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/awx/main/tasks.py b/awx/main/tasks.py index eb2d48546d..48d5a54086 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -73,6 +73,7 @@ from awx.main.utils import (get_ssh_version, update_scm_url, ignore_inventory_computed_fields, ignore_inventory_group_removal, extract_ansible_vars, schedule_task_manager, get_awx_version) +from awx.main.utils.ansible import read_ansible_config from awx.main.utils.common import get_ansible_version, _get_ansible_version, get_custom_venv_choices from awx.main.utils.safe_yaml import safe_dump, sanitize_jinja from awx.main.utils.reload import stop_local_services @@ -1529,14 +1530,22 @@ class RunJob(BaseTask): if authorize: env['ANSIBLE_NET_AUTH_PASS'] = network_cred.get_input('authorize_password', default='') - for env_key, folder, default in ( - ('ANSIBLE_COLLECTIONS_PATHS', 'requirements_collections', '~/.ansible/collections:/usr/share/ansible/collections'), - ('ANSIBLE_ROLES_PATH', 'requirements_roles', '~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles')): + path_vars = ( + ('ANSIBLE_COLLECTIONS_PATHS', 'collections_paths', 'requirements_collections', '~/.ansible/collections:/usr/share/ansible/collections'), + ('ANSIBLE_ROLES_PATH', 'roles_path', 'requirements_roles', '~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles')) + + config_values = read_ansible_config(job.project.get_project_path(), list(map(lambda x: x[1], path_vars))) + + for env_key, config_setting, folder, default in path_vars: paths = default.split(':') if env_key in env: for path in env[env_key].split(':'): if path not in paths: paths = [env[env_key]] + paths + elif config_setting in config_values: + for path in config_values[config_setting].split(':'): + if path not in paths: + paths = [config_values[config_setting]] + paths paths = [os.path.join(private_data_dir, folder)] + paths env[env_key] = os.pathsep.join(paths) diff --git a/awx/main/utils/ansible.py b/awx/main/utils/ansible.py index 7e68d88189..287d5ba94f 100644 --- a/awx/main/utils/ansible.py +++ b/awx/main/utils/ansible.py @@ -5,11 +5,15 @@ import codecs import re import os +import logging from itertools import islice +from configparser import ConfigParser # Django from django.utils.encoding import smart_str +logger = logging.getLogger('awx.main.utils.ansible') + __all__ = ['skip_directory', 'could_be_playbook', 'could_be_inventory'] @@ -97,3 +101,20 @@ def could_be_inventory(project_path, dir_path, filename): except IOError: return None return inventory_rel_path + + +def read_ansible_config(project_path, variables_of_interest): + fnames = ['/etc/ansible/ansible.cfg'] + if project_path: + fnames.insert(0, os.path.join(project_path, 'ansible.cfg')) + values = {} + try: + parser = ConfigParser() + parser.read(fnames) + if 'defaults' in parser: + for var in variables_of_interest: + if var in parser['defaults']: + values[var] = parser['defaults'][var] + except Exception as e: + logger.warn('Failed to read ansible configuration(s) {}: {}'.format(fnames, e)) + return values From 60ca843b71979743a94b04cf2df9ac50febe6850 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Tue, 15 Oct 2019 14:20:09 -0400 Subject: [PATCH 2/2] Use logger.exception instead of logger.warning. --- awx/main/utils/ansible.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awx/main/utils/ansible.py b/awx/main/utils/ansible.py index 287d5ba94f..06f56383c1 100644 --- a/awx/main/utils/ansible.py +++ b/awx/main/utils/ansible.py @@ -116,5 +116,5 @@ def read_ansible_config(project_path, variables_of_interest): if var in parser['defaults']: values[var] = parser['defaults'][var] except Exception as e: - logger.warn('Failed to read ansible configuration(s) {}: {}'.format(fnames, e)) + logger.exception('Failed to read ansible configuration(s) {}'.format(fnames)) return values