From 9255a618e307b4e087cb0f3f6f4f225f7652c298 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Mon, 25 Jul 2016 08:11:45 -0400 Subject: [PATCH] set cwd to task's basedir (#16805) * switch cwd to basedir of task This restores previous behaviour in pre 2.0 and allows for 'local type' plugins and actions to have a more predictable relative path. fixes #14489 * removed FIXME since prev commit 'fixes' this * fix tests, now they need a loader (thanks jimi!) (cherry picked from commit e2f17f8d9b212b1e8d65c12a778d036753831ab6) --- lib/ansible/plugins/action/__init__.py | 9 ++++++++- lib/ansible/plugins/connection/local.py | 1 - test/units/plugins/action/test_action.py | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index 40d8f227491..080488bb555 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -711,7 +711,14 @@ class ActionBase(with_metaclass(ABCMeta, object)): cmd = executable + ' -c ' + pipes.quote(cmd) display.debug("_low_level_execute_command(): executing: %s" % (cmd,)) - rc, stdout, stderr = self._connection.exec_command(cmd, in_data=in_data, sudoable=sudoable) + + # Change directory to basedir of task for command execution + cwd = os.getcwd() + os.chdir(self._loader.get_basedir()) + try: + rc, stdout, stderr = self._connection.exec_command(cmd, in_data=in_data, sudoable=sudoable) + finally: + os.chdir(cwd) # stdout and stderr may be either a file-like or a bytes object. # Convert either one to a text type diff --git a/lib/ansible/plugins/connection/local.py b/lib/ansible/plugins/connection/local.py index c66218b882f..0c7bb5ccb7f 100644 --- a/lib/ansible/plugins/connection/local.py +++ b/lib/ansible/plugins/connection/local.py @@ -69,7 +69,6 @@ class Connection(ConnectionBase): executable = C.DEFAULT_EXECUTABLE.split()[0] if C.DEFAULT_EXECUTABLE else None display.vvv(u"EXEC {0}".format(cmd), host=self._play_context.remote_addr) - # FIXME: cwd= needs to be set to the basedir of the playbook display.debug("opening command with Popen()") if isinstance(cmd, (text_type, binary_type)): diff --git a/test/units/plugins/action/test_action.py b/test/units/plugins/action/test_action.py index 440b2e2aaab..a9c66d2c532 100644 --- a/test/units/plugins/action/test_action.py +++ b/test/units/plugins/action/test_action.py @@ -607,8 +607,10 @@ class TestActionBase(unittest.TestCase): self.assertRaises(AnsibleError, action_base._execute_module) def test_action_base_sudo_only_if_user_differs(self): + fake_loader = MagicMock() + fake_loader.get_basedir.return_value = os.getcwd() play_context = PlayContext() - action_base = DerivedActionBase(None, None, play_context, None, None, None) + action_base = DerivedActionBase(None, None, play_context, fake_loader, None, None) action_base._connection = MagicMock(exec_command=MagicMock(return_value=(0, '', ''))) action_base._connection._shell = MagicMock(append_command=MagicMock(return_value=('JOINED CMD')))