diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index 6632bdc51d..5f1182eb78 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -71,7 +71,7 @@ DEFAULTS='defaults' # configurable things DEFAULT_HOST_LIST = shell_expand_path(get_config(p, DEFAULTS, 'hostfile', 'ANSIBLE_HOSTS', '/etc/ansible/hosts')) -DEFAULT_MODULE_PATH = shell_expand_path(get_config(p, DEFAULTS, 'library', 'ANSIBLE_LIBRARY', DIST_MODULE_PATH)) +DEFAULT_MODULE_PATH = get_config(p, DEFAULTS, 'library', 'ANSIBLE_LIBRARY', DIST_MODULE_PATH) DEFAULT_REMOTE_TMP = shell_expand_path(get_config(p, DEFAULTS, 'remote_tmp', 'ANSIBLE_REMOTE_TEMP', '$HOME/.ansible/tmp')) DEFAULT_MODULE_NAME = get_config(p, DEFAULTS, 'module_name', None, 'command') DEFAULT_PATTERN = get_config(p, DEFAULTS, 'pattern', None, '*') @@ -98,12 +98,12 @@ DEFAULT_LEGACY_PLAYBOOK_VARIABLES = get_config(p, DEFAULTS, 'legacy_playbook_var DEFAULT_JINJA2_EXTENSIONS = get_config(p, DEFAULTS, 'jinja2_extensions', 'ANSIBLE_JINJA2_EXTENSIONS', None) DEFAULT_EXECUTABLE = get_config(p, DEFAULTS, 'executable', 'ANSIBLE_EXECUTABLE', '/bin/sh') -DEFAULT_ACTION_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'action_plugins', 'ANSIBLE_ACTION_PLUGINS', '/usr/share/ansible_plugins/action_plugins')) -DEFAULT_CALLBACK_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'callback_plugins', 'ANSIBLE_CALLBACK_PLUGINS', '/usr/share/ansible_plugins/callback_plugins')) -DEFAULT_CONNECTION_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'connection_plugins', 'ANSIBLE_CONNECTION_PLUGINS', '/usr/share/ansible_plugins/connection_plugins')) -DEFAULT_LOOKUP_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'lookup_plugins', 'ANSIBLE_LOOKUP_PLUGINS', '/usr/share/ansible_plugins/lookup_plugins')) -DEFAULT_VARS_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'vars_plugins', 'ANSIBLE_VARS_PLUGINS', '/usr/share/ansible_plugins/vars_plugins')) -DEFAULT_FILTER_PLUGIN_PATH = shell_expand_path(get_config(p, DEFAULTS, 'filter_plugins', 'ANSIBLE_FILTER_PLUGINS', '/usr/share/ansible_plugins/filter_plugins')) +DEFAULT_ACTION_PLUGIN_PATH = get_config(p, DEFAULTS, 'action_plugins', 'ANSIBLE_ACTION_PLUGINS', '/usr/share/ansible_plugins/action_plugins') +DEFAULT_CALLBACK_PLUGIN_PATH = get_config(p, DEFAULTS, 'callback_plugins', 'ANSIBLE_CALLBACK_PLUGINS', '/usr/share/ansible_plugins/callback_plugins') +DEFAULT_CONNECTION_PLUGIN_PATH = get_config(p, DEFAULTS, 'connection_plugins', 'ANSIBLE_CONNECTION_PLUGINS', '/usr/share/ansible_plugins/connection_plugins') +DEFAULT_LOOKUP_PLUGIN_PATH = get_config(p, DEFAULTS, 'lookup_plugins', 'ANSIBLE_LOOKUP_PLUGINS', '/usr/share/ansible_plugins/lookup_plugins') +DEFAULT_VARS_PLUGIN_PATH = get_config(p, DEFAULTS, 'vars_plugins', 'ANSIBLE_VARS_PLUGINS', '/usr/share/ansible_plugins/vars_plugins') +DEFAULT_FILTER_PLUGIN_PATH = get_config(p, DEFAULTS, 'filter_plugins', 'ANSIBLE_FILTER_PLUGINS', '/usr/share/ansible_plugins/filter_plugins') DEFAULT_LOG_PATH = shell_expand_path(get_config(p, DEFAULTS, 'log_path', 'ANSIBLE_LOG_PATH', '')) ANSIBLE_NOCOWS = get_config(p, DEFAULTS, 'nocows', 'ANSIBLE_NOCOWS', None) diff --git a/lib/ansible/utils/plugins.py b/lib/ansible/utils/plugins.py index c7fb2c4782..160bccaf9e 100644 --- a/lib/ansible/utils/plugins.py +++ b/lib/ansible/utils/plugins.py @@ -16,6 +16,7 @@ # along with Ansible. If not, see . import os +import os.path import sys import glob import imp @@ -108,6 +109,7 @@ class PluginLoader(object): # look in any configured plugin paths, allow one level deep for subcategories configured_paths = self.config.split(os.pathsep) for path in configured_paths: + path = os.path.expanduser(path) contents = glob.glob("%s/*" % path) for c in contents: if os.path.isdir(c): diff --git a/test/TestUtils.py b/test/TestUtils.py index 1a3d488985..61fe445c29 100644 --- a/test/TestUtils.py +++ b/test/TestUtils.py @@ -1,6 +1,11 @@ # -*- coding: utf-8 -*- import unittest +import os +import os.path +import tempfile + +from nose.plugins.skip import SkipTest import ansible.utils import ansible.utils.template as template2 @@ -376,3 +381,45 @@ class TestUtils(unittest.TestCase): def test_parse_kv_basic(self): assert (ansible.utils.parse_kv('a=simple b="with space" c="this=that"') == {'a': 'simple', 'b': 'with space', 'c': 'this=that'}) + + ##################################### + ### plugins + + def test_loaders_expanduser_each_dir(self): + # Test that PluginLoader will call expanduser on each path + # when it splits its "config" argument. + home_dir = os.path.expanduser("~") + if home_dir == "~": + raise SkipTest("your platform doesn't expand ~ in paths") + elif not os.path.isdir(home_dir): + raise SkipTest("~ expands to non-directory %r" % (home_dir,)) + elif not os.path.isabs(home_dir): + raise SkipTest("~ expands to non-absolute path %r" % (home_dir,)) + # Unfortunately we have to create temporary directories in + # your home directory; the directories have to exist for + # PluginLoader to accept them. + abs_dirs, tilde_dirs = [], [] + try: + for _ in range(2): + temp_dir = tempfile.mkdtemp(prefix="ansible", dir=home_dir) + abs_dirs.append(temp_dir) + # Convert mkdtemp's absolute path to one starting with "~". + tilde_dir = os.path.join("~", os.path.relpath(temp_dir, + home_dir)) + tilde_dirs.append(tilde_dir) + loader = ansible.utils.plugins.PluginLoader( + "", + "", + os.pathsep.join(tilde_dirs), + "something_under_basedir" + ) + loader_paths = loader.print_paths().split(os.pathsep) + for abs_dir in abs_dirs: + assert abs_dir in loader_paths, \ + "%r not in %r" % (abs_dir, loader_paths) + finally: + for a_dir in abs_dirs: + try: + os.rmdir(a_dir) + except os.error: + pass