From 4e5b0dedb9759e26edcd5a072d823034ae592640 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Wed, 22 Feb 2017 13:40:53 -0500 Subject: [PATCH] Fix infinite recursion on action module import Ansible imports our module with the name ansible.plugins.action.normal (regardless of its actual path). This line would then import the original module, also under the same name, so it would overwrite ours. Correct this by importing the original with a unique name. It's not actually used anywhere anyway. Change-Id: I5dd26e2f89399f991cebc23839a36e7aff47056c --- zuul/ansible/action/normal.py | 8 ++------ zuul/ansible/paths.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/zuul/ansible/action/normal.py b/zuul/ansible/action/normal.py index a50125cb43..b18cb51a60 100644 --- a/zuul/ansible/action/normal.py +++ b/zuul/ansible/action/normal.py @@ -13,12 +13,8 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -# TODO(mordred) Figure out how to not need to do this to get the base class -import ansible.plugins.action -import imp -normal = imp.load_module( - 'ansible.plugins.action.normal', - *imp.find_module('normal', ansible.plugins.action.__path__)) +from zuul.ansible import paths +normal = paths._import_ansible_action_plugin('normal') class ActionModule(normal.ActionModule): diff --git a/zuul/ansible/paths.py b/zuul/ansible/paths.py index 2bd018117a..cde43f1d45 100644 --- a/zuul/ansible/paths.py +++ b/zuul/ansible/paths.py @@ -13,8 +13,11 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . +import imp import os +import ansible.plugins.action + def _is_safe_path(path): if os.path.isabs(path): @@ -31,3 +34,21 @@ def _fail_dict(path, prefix='Accessing files from'): path=path, msg="{prefix} outside the working dir is prohibited".format( prefix=prefix)) + + +def _import_ansible_action_plugin(name): + # Ansible forces the import of our action plugins + # (zuul.ansible.action.foo) as ansible.plugins.action.foo, which + # is the import path of the ansible implementation. Our + # implementations need to subclass that, but if we try to import + # it with that name, we will get our own module. This bypasses + # Python's module namespace to load the actual ansible modules. + # We need to give it a name, however. If we load it with its + # actual name, we will end up overwriting our module in Python's + # namespace, causing infinite recursion. So we supply an + # otherwise unused name for the module: + # zuul.ansible.protected.action.foo. + + return imp.load_module( + 'zuul.ansible.protected.action.' + name, + *imp.find_module(name, ansible.plugins.action.__path__))