From 611d56dc4ce3abe3f80eb0a72456f2c071b99df4 Mon Sep 17 00:00:00 2001 From: Dale Sedivec Date: Fri, 24 May 2013 17:05:28 -0500 Subject: [PATCH] Plug-ins loaded from top-level plug-in directory PluginLoader._get_paths, as of 391fb98e, was only finding plug-ins that were in a subdirectory of one of the basedirs (i.e. in a category directory). For example, action_plugins/foo.py would never be loaded, but action_plugins/bar/foo.py would work. This makes it so that "uncategorized" plug-ins in the top level of a directory such as action_plugins will be loaded, though plug-ins in a "category" subdirectory will still be preferred. For example, action_plugins/bar/foo.py would be preferred over action_plugins/foo.py. --- lib/ansible/utils/plugins.py | 5 ++--- test/TestRunner.py | 7 +++++++ test/action_plugins/categorized_plugin.py | 15 +++++++++++++++ .../action_plugins/category/categorized_plugin.py | 11 +++++++++++ test/action_plugins/uncategorized_plugin.py | 11 +++++++++++ 5 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 test/action_plugins/categorized_plugin.py create mode 100644 test/action_plugins/category/categorized_plugin.py create mode 100644 test/action_plugins/uncategorized_plugin.py diff --git a/lib/ansible/utils/plugins.py b/lib/ansible/utils/plugins.py index c36e5434aeb..e9d2c605bd4 100644 --- a/lib/ansible/utils/plugins.py +++ b/lib/ansible/utils/plugins.py @@ -100,11 +100,10 @@ class PluginLoader(object): files = glob.glob("%s/*" % fullpath) for file in files: if os.path.isdir(file) and file not in ret: - ret.append(file) - else: + ret.append(file) if fullpath not in ret: ret.append(fullpath) - + # look in any configured plugin paths, allow one level deep for subcategories configured_paths = self.config.split(os.pathsep) for path in configured_paths: diff --git a/test/TestRunner.py b/test/TestRunner.py index cf17e669986..d833a01be0c 100644 --- a/test/TestRunner.py +++ b/test/TestRunner.py @@ -27,6 +27,7 @@ class TestRunner(unittest.TestCase): def setUp(self): self.user = getpass.getuser() self.runner = ansible.runner.Runner( + basedir='test/', module_name='ping', module_path='library/', module_args='', @@ -77,6 +78,12 @@ class TestRunner(unittest.TestCase): assert "localhost" in results['contacted'] return results['contacted']['localhost'] + def test_action_plugins(self): + result = self._run("uncategorized_plugin", []) + assert result.get("msg") == "uncategorized" + result = self._run("categorized_plugin", []) + assert result.get("msg") == "categorized" + def test_ping(self): result = self._run('ping', []) assert "ping" in result diff --git a/test/action_plugins/categorized_plugin.py b/test/action_plugins/categorized_plugin.py new file mode 100644 index 00000000000..62fa6ab5100 --- /dev/null +++ b/test/action_plugins/categorized_plugin.py @@ -0,0 +1,15 @@ +from ansible.runner import return_data + + +class ActionModule (object): + def __init__(self, runner): + self.runner = runner + + def run(self, conn, tmp, module_name, module_args, inject, + complex_args=None, **kwargs): + # This plug-in should be ignored in deference to + # category/categorized_plugin.py, so it should never actually + # run. + return return_data.ReturnData( + conn=conn, comm_ok=True, + result={"msg": "this plug-in should never be run"}) diff --git a/test/action_plugins/category/categorized_plugin.py b/test/action_plugins/category/categorized_plugin.py new file mode 100644 index 00000000000..da23814c181 --- /dev/null +++ b/test/action_plugins/category/categorized_plugin.py @@ -0,0 +1,11 @@ +from ansible.runner import return_data + + +class ActionModule (object): + def __init__(self, runner): + self.runner = runner + + def run(self, conn, tmp, module_name, module_args, inject, + complex_args=None, **kwargs): + return return_data.ReturnData(conn=conn, comm_ok=True, + result={"msg": "categorized"}) diff --git a/test/action_plugins/uncategorized_plugin.py b/test/action_plugins/uncategorized_plugin.py new file mode 100644 index 00000000000..bf4bf809bd9 --- /dev/null +++ b/test/action_plugins/uncategorized_plugin.py @@ -0,0 +1,11 @@ +from ansible.runner import return_data + + +class ActionModule (object): + def __init__(self, runner): + self.runner = runner + + def run(self, conn, tmp, module_name, module_args, inject, + complex_args=None, **kwargs): + return return_data.ReturnData(conn=conn, comm_ok=True, + result={"msg": "uncategorized"})