diff --git a/oslo_concurrency/processutils.py b/oslo_concurrency/processutils.py index 744c849..8479a3a 100644 --- a/oslo_concurrency/processutils.py +++ b/oslo_concurrency/processutils.py @@ -262,6 +262,10 @@ def execute(*cmd, **kwargs): :param prlimit: Set resource limits on the child process. See below for a detailed description. :type prlimit: :class:`ProcessLimits` + :param python_exec: The python executable to use for enforcing + prlimits. If this is not set it will default to use + sys.executable. + :type python_exec: string :returns: (stdout, stderr) from process execution :raises: :class:`UnknownArgumentError` on receiving unknown arguments @@ -314,6 +318,7 @@ def execute(*cmd, **kwargs): on_completion = kwargs.pop('on_completion', None) preexec_fn = kwargs.pop('preexec_fn', None) prlimit = kwargs.pop('prlimit', None) + python_exec = kwargs.pop('python_exec', sys.executable) if isinstance(check_exit_code, bool): ignore_exit_code = not check_exit_code @@ -350,7 +355,7 @@ def execute(*cmd, **kwargs): _('Process resource limits are ignored as ' 'this feature is not supported on Windows.')) else: - args = [sys.executable, '-m', 'oslo_concurrency.prlimit'] + args = [python_exec, '-m', 'oslo_concurrency.prlimit'] args.extend(prlimit.prlimit_args()) args.append('--') args.extend(cmd) diff --git a/oslo_concurrency/tests/unit/test_processutils.py b/oslo_concurrency/tests/unit/test_processutils.py index 29b4c65..29576e5 100644 --- a/oslo_concurrency/tests/unit/test_processutils.py +++ b/oslo_concurrency/tests/unit/test_processutils.py @@ -968,3 +968,16 @@ class PrlimitTestCase(test_base.BaseTestCase): stderr=mock.ANY, close_fds=mock.ANY, preexec_fn=mock.ANY, shell=mock.ANY, cwd=mock.ANY, env=mock.ANY) + + @mock.patch.object(processutils.subprocess, 'Popen') + def test_python_exec(self, sub_mock): + mock_subprocess = mock.MagicMock() + mock_subprocess.communicate.return_value = (b'', b'') + sub_mock.return_value = mock_subprocess + args = ['/a/command'] + prlimit = self.limit_address_space() + + processutils.execute(*args, prlimit=prlimit, check_exit_code=False, + python_exec='/fake_path') + python_path = sub_mock.mock_calls[0][1][0][0] + self.assertEqual('/fake_path', python_path) diff --git a/releasenotes/notes/add-python-exec-kwarg-3a7a0c0849f9bb21.yaml b/releasenotes/notes/add-python-exec-kwarg-3a7a0c0849f9bb21.yaml new file mode 100644 index 0000000..852d3fc --- /dev/null +++ b/releasenotes/notes/add-python-exec-kwarg-3a7a0c0849f9bb21.yaml @@ -0,0 +1,5 @@ +--- +features: + - A new kwarg, ``python_exec`` is added to the execute() function in the + processutils module. This option is used to specify the path to the python + executable to use for prlimits enforcement.