diff --git a/awxkit/awxkit/api/pages/unified_jobs.py b/awxkit/awxkit/api/pages/unified_jobs.py index 8954eec30b..987391364d 100644 --- a/awxkit/awxkit/api/pages/unified_jobs.py +++ b/awxkit/awxkit/api/pages/unified_jobs.py @@ -139,15 +139,18 @@ class UnifiedJob(HasStatus, base.Base): """ self.get() job_args = self.job_args - expected_prefix = '/tmp/awx_{}'.format(self.id) + expected_segment = 'awx_{}'.format(self.id) for arg1, arg2 in zip(job_args[:-1], job_args[1:]): if arg1 == '-v': if ':' in arg2: host_loc = arg2.split(':')[0] - if host_loc.startswith(expected_prefix): + parts = host_loc.rstrip('/').split('/') + if any(p == expected_segment or p.startswith(expected_segment + '_') for p in parts): return host_loc raise RuntimeError( - 'Could not find a controller private_data_dir for this job. Searched for volume mount to {} inside of args {}'.format(expected_prefix, job_args) + 'Could not find a controller private_data_dir for this job. Searched for volume mount matching {} inside of args {}'.format( + expected_segment, job_args + ) ) diff --git a/awxkit/test/test_unified_jobs.py b/awxkit/test/test_unified_jobs.py new file mode 100644 index 0000000000..4f959d6c3b --- /dev/null +++ b/awxkit/test/test_unified_jobs.py @@ -0,0 +1,71 @@ +from unittest import mock + +import pytest + +from awxkit.api.pages.unified_jobs import UnifiedJob + + +def _make_job(job_id, job_args): + """Create a minimal UnifiedJob mock with the given id and job_args.""" + job = mock.MagicMock(spec=UnifiedJob) + job.id = job_id + job.get = mock.MagicMock() + type(job).job_args = mock.PropertyMock(return_value=job_args) + type(job).controller_dir = UnifiedJob.controller_dir + return job + + +class TestControllerDir: + def test_traditional_path(self): + job = _make_job(4387, ['podman', 'run', '-v', '/tmp/awx_4387_qv4aqn_8/:/runner/:Z', '--name', 'test']) + assert job.controller_dir == '/tmp/awx_4387_qv4aqn_8/' + + def test_containerized_path(self): + job = _make_job( + 4387, + [ + 'podman', + 'run', + '-v', + '/home/ansible/aap/controller/data/job_execution/awx_4387_qv4aqn_8/:/runner/:Z', + '--name', + 'test', + ], + ) + assert job.controller_dir == '/home/ansible/aap/controller/data/job_execution/awx_4387_qv4aqn_8/' + + def test_no_false_match_on_similar_id(self): + job = _make_job(1, ['podman', 'run', '-v', '/tmp/awx_10_abc/:/runner/:Z', '--name', 'test']) + with pytest.raises(RuntimeError, match='Could not find a controller private_data_dir'): + _ = job.controller_dir + + def test_exact_segment_match(self): + job = _make_job(1, ['podman', 'run', '-v', '/tmp/awx_1/:/runner/:Z', '--name', 'test']) + assert job.controller_dir == '/tmp/awx_1/' + + def test_segment_with_suffix(self): + job = _make_job(1, ['podman', 'run', '-v', '/tmp/awx_1_abc/:/runner/:Z', '--name', 'test']) + assert job.controller_dir == '/tmp/awx_1_abc/' + + def test_no_volume_mounts_raises(self): + job = _make_job(99, ['podman', 'run', '--name', 'test']) + with pytest.raises(RuntimeError, match='Could not find a controller private_data_dir'): + _ = job.controller_dir + + def test_multiple_volumes_picks_correct(self): + job = _make_job( + 42, + [ + 'podman', + 'run', + '-v', + '/etc/pki:/etc/pki:O', + '-v', + '/home/ansible/aap/controller/data/job_execution/awx_42_xyz/:/runner/:Z', + '-v', + '/usr/share/pki:/usr/share/pki:O', + '--name', + 'test', + ], + ) + assert job.controller_dir == '/home/ansible/aap/controller/data/job_execution/awx_42_xyz/'