diff --git a/oslo_concurrency/processutils.py b/oslo_concurrency/processutils.py index 4b9ead4..d26856b 100644 --- a/oslo_concurrency/processutils.py +++ b/oslo_concurrency/processutils.py @@ -24,41 +24,18 @@ import os import random import shlex import signal +import subprocess import sys import time -import warnings import enum from oslo_utils import encodeutils -from oslo_utils import importutils from oslo_utils import strutils from oslo_utils import timeutils from oslo_concurrency._i18n import _ -if os.name == 'nt': - warnings.warn('Support for Windows OS is deprecated.', - category=DeprecationWarning) - - -eventlet = importutils.try_import('eventlet') -if eventlet: - from eventlet import tpool - -eventlet_patched = (eventlet and - eventlet.patcher.is_monkey_patched('subprocess')) -if eventlet_patched and os.name == 'nt': - # subprocess.Popen.communicate will spawn two threads consuming - # stdout/stderr when passing data through stdin. We need to make - # sure that *native* threads will be used as pipes are blocking - # on Windows. - subprocess = eventlet.patcher.original('subprocess') - subprocess.threading = eventlet.patcher.original('threading') -else: - import subprocess - - LOG = logging.getLogger(__name__) @@ -355,16 +332,11 @@ def execute(*cmd, **kwargs): cmd = [str(c) for c in cmd] if prlimit: - if os.name == 'nt': - LOG.log(loglevel, - _('Process resource limits are ignored as ' - 'this feature is not supported on Windows.')) - else: - args = [python_exec, '-m', 'oslo_concurrency.prlimit'] - args.extend(prlimit.prlimit_args()) - args.append('--') - args.extend(cmd) - cmd = args + args = [python_exec, '-m', 'oslo_concurrency.prlimit'] + args.extend(prlimit.prlimit_args()) + args.append('--') + args.extend(cmd) + cmd = args sanitized_cmd = strutils.mask_password(' '.join(cmd)) @@ -377,19 +349,13 @@ def execute(*cmd, **kwargs): LOG.log(loglevel, _('Running cmd (subprocess): %s'), sanitized_cmd) _PIPE = subprocess.PIPE # pylint: disable=E1101 - if os.name == 'nt': - on_preexec_fn = None - close_fds = False - else: - on_preexec_fn = functools.partial(_subprocess_setup, - preexec_fn) - close_fds = True + on_preexec_fn = functools.partial(_subprocess_setup, preexec_fn) obj = subprocess.Popen(cmd, stdin=_PIPE, stdout=_PIPE, stderr=_PIPE, - close_fds=close_fds, + close_fds=True, preexec_fn=on_preexec_fn, shell=shell, cwd=cwd, @@ -399,16 +365,7 @@ def execute(*cmd, **kwargs): on_execute(obj) try: - # eventlet.green.subprocess is not really greenthread friendly - # on Windows. In order to avoid blocking other greenthreads, - # we have to wrap this call using tpool. - if eventlet_patched and os.name == 'nt': - result = tpool.execute(obj.communicate, - process_input, - timeout=timeout) - else: - result = obj.communicate(process_input, - timeout=timeout) + result = obj.communicate(process_input, timeout=timeout) obj.stdin.close() # pylint: disable=E1101 _returncode = obj.returncode # pylint: disable=E1101 diff --git a/oslo_concurrency/tests/unit/test_processutils.py b/oslo_concurrency/tests/unit/test_processutils.py index b4f1493..8ff1fd9 100644 --- a/oslo_concurrency/tests/unit/test_processutils.py +++ b/oslo_concurrency/tests/unit/test_processutils.py @@ -117,45 +117,6 @@ class UtilsTest(test_base.BaseTestCase): if type(e).__name__ != 'SubprocessError': raise - @mock.patch.object(os, 'name', 'nt') - @mock.patch.object(processutils.subprocess, "Popen") - @mock.patch.object(processutils, 'tpool', create=True) - def _test_windows_execute(self, mock_tpool, mock_popen, - use_eventlet=False): - # We want to ensure that if eventlet is used on Windows, - # 'communicate' calls are wrapped with eventlet.tpool.execute. - mock_comm = mock_popen.return_value.communicate - mock_comm.return_value = None - mock_tpool.execute.return_value = mock_comm.return_value - - fake_pinput = b'fake pinput' - - with mock.patch.object(processutils, 'eventlet_patched', - use_eventlet): - processutils.execute( - TRUE_UTILITY, - process_input=fake_pinput, - check_exit_code=False) - - mock_popen.assert_called_once_with( - [TRUE_UTILITY], - stdin=mock.ANY, stdout=mock.ANY, - stderr=mock.ANY, close_fds=mock.ANY, - preexec_fn=mock.ANY, shell=mock.ANY, - cwd=mock.ANY, env=mock.ANY) - - if use_eventlet: - mock_tpool.execute.assert_called_once_with( - mock_comm, fake_pinput, timeout=None) - else: - mock_comm.assert_called_once_with(fake_pinput, timeout=None) - - def test_windows_execute_without_eventlet(self): - self._test_windows_execute() - - def test_windows_execute_using_eventlet(self): - self._test_windows_execute(use_eventlet=True) - class ProcessExecutionErrorTest(test_base.BaseTestCase): @@ -954,28 +915,6 @@ class PrlimitTestCase(test_base.BaseTestCase): else: self.fail("ProcessExecutionError not raised") - @mock.patch.object(os, 'name', 'nt') - @mock.patch.object(processutils.subprocess, "Popen") - def test_prlimit_windows(self, mock_popen): - # We want to ensure that process resource limits are - # ignored on Windows, in which case this feature is not - # supported. We'll just check the command passed to Popen, - # which is expected to be unaltered. - prlimit = self.limit_address_space() - mock_popen.return_value.communicate.return_value = None - - processutils.execute( - *self.SIMPLE_PROGRAM, - prlimit=prlimit, - check_exit_code=False) - - mock_popen.assert_called_once_with( - self.SIMPLE_PROGRAM, - stdin=mock.ANY, stdout=mock.ANY, - 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() diff --git a/releasenotes/notes/remove-windows-bad63cd41c15235d.yaml b/releasenotes/notes/remove-windows-bad63cd41c15235d.yaml new file mode 100644 index 0000000..885de06 --- /dev/null +++ b/releasenotes/notes/remove-windows-bad63cd41c15235d.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - | + This library no longer supports Windows operating systems.