Skip to content

Commit

Permalink
Fix invalid inventory with relative pvt data dir (#1316)
Browse files Browse the repository at this point in the history
Since the current working directory is set to the location of the
playbook being executed, a relative pvt data directory would cause
an invalid inventory path if a custom inventory was provided.
  • Loading branch information
Shrews authored Nov 6, 2023
1 parent aed342f commit 481fc28
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/ansible_runner/config/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,20 @@ def prepare(self):
def prepare_inventory(self):
"""
Prepares the inventory default under ``private_data_dir`` if it's not overridden by the constructor.
We make sure that if inventory is a path, that it is an absolute path.
"""
if self.containerized:
self.inventory = '/runner/inventory'
return

if self.inventory is None:
# At this point we expect self.private_data_dir to be an absolute path
# since that is expanded in the base class.
if os.path.exists(os.path.join(self.private_data_dir, "inventory")):
self.inventory = os.path.join(self.private_data_dir, "inventory")
elif isinstance(self.inventory, str) and os.path.exists(self.inventory):
self.inventory = os.path.abspath(self.inventory)

def prepare_env(self):
"""
Expand Down
48 changes: 48 additions & 0 deletions test/integration/test_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,3 +559,51 @@ def test_get_role_argspec_within_container(project_fixtures, runtime, skipif_pre
assert isinstance(resp, dict)
assert 'Into_The_Mystic' in resp
assert resp['Into_The_Mystic']['entry_points'] == expected_epoint


class TestRelativePvtDataDirPaths:
"""
Class to handle test setup/teardown of tests that need to change working
directory to test relative paths.
"""

def setup_method(self):
self._old_workdir = os.getcwd() # pylint: disable=W0201

def teardown_method(self):
os.chdir(self._old_workdir)

def test_inventory_as_string(self, project_fixtures):
"""
Test of bug fix for GH issue #1216: https://github.com/ansible/ansible-runner/issues/1216
A relative private data directory combined with an inventory specified as a string
would produce an invalid inventory path being passed along to ansible.
"""
os.chdir(str(project_fixtures))

inventory = 'hostA ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"'

r = run(private_data_dir='debug',
inventory=inventory,
playbook='debug.yml')

with r.stdout as output:
text = output.read()

assert r.status == 'successful'
assert "No inventory was parsed" not in text

def test_default_inventory(self, project_fixtures):
"""
Test relative pvt data dir with the default inventory.
"""
os.chdir(str(project_fixtures))

r = run(private_data_dir='debug', playbook='debug.yml')

with r.stdout as output:
text = output.read()

assert r.status == 'successful'
assert "No inventory was parsed" not in text
5 changes: 4 additions & 1 deletion test/unit/config/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,16 @@ def test_prepare_inventory(mocker):
rc = RunnerConfig(private_data_dir='/')
rc.prepare_inventory()
assert rc.inventory == '/inventory'

rc.inventory = '/tmp/inventory'
rc.prepare_inventory()
assert rc.inventory == '/tmp/inventory'

path_exists.return_value = False
rc.inventory = 'localhost,anotherhost,'
rc.prepare_inventory()
assert rc.inventory == 'localhost,anotherhost,'
path_exists.return_value = False

rc.inventory = None
rc.prepare_inventory()
assert rc.inventory is None
Expand Down

0 comments on commit 481fc28

Please sign in to comment.