From 552819e7658d8a8764a3d4d8976e9ac3ba6c49c6 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Tue, 23 Nov 2021 23:46:47 +0000 Subject: [PATCH] mitogen.parent: Detect and avoid Python2.7 wrapper on macOS 11 & 12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this errors such as the following occur ``` ✗ MITOGEN_LOG_LEVEL=DEBUG python3 foo.py Python: execv: (null): No such file or directory Traceback (most recent call last): File "foo.py", line 16, in target = router.local(python_path='/usr/bin/python2.7', debug=True) File "/Users/alex/src/mitogen2/mitogen/parent.py", line 2486, in local return self.connect(u'local', **kwargs) File "/Users/alex/src/mitogen2/mitogen/parent.py", line 2446, in connect return self._connect(klass, **mitogen.core.Kwargs(kwargs)) File "/Users/alex/src/mitogen2/mitogen/parent.py", line 2426, in _connect conn.connect(context=context) File "/Users/alex/src/mitogen2/mitogen/parent.py", line 1708, in connect raise self.exception mitogen.parent.EofError: EOF on stream; last 100 lines received: MITO000 MITO001 ``` Before ``` $ ./preamble_size.py SSH command size: 625 Bootstrap (mitogen.core) size: 17007 (16.61KiB) Original Minimized Compressed mitogen.parent 97496 95.2KiB 50355 49.2KiB 51.6% 12663 12.4KiB 13.0% mitogen.fork 8436 8.2KiB 4130 4.0KiB 49.0% 1648 1.6KiB 19.5% mitogen.ssh 10892 10.6KiB 6952 6.8KiB 63.8% 2113 2.1KiB 19.4% mitogen.sudo 12089 11.8KiB 5924 5.8KiB 49.0% 2249 2.2KiB 18.6% mitogen.select 12325 12.0KiB 2929 2.9KiB 23.8% 964 0.9KiB 7.8% mitogen.service 41644 40.7KiB 22431 21.9KiB 53.9% 5886 5.7KiB 14.1% mitogen.fakessh 15599 15.2KiB 8011 7.8KiB 51.4% 2624 2.6KiB 16.8% mitogen.master 48732 47.6KiB 24569 24.0KiB 50.4% 6768 6.6KiB 13.9% ``` After ``` $ ./preamble_size.py SSH command size: 705 Bootstrap (mitogen.core) size: 17007 (16.61KiB) Original Minimized Compressed mitogen.parent 97885 95.6KiB 50516 49.3KiB 51.6% 12728 12.4KiB 13.0% mitogen.fork 8436 8.2KiB 4130 4.0KiB 49.0% 1648 1.6KiB 19.5% mitogen.ssh 10892 10.6KiB 6952 6.8KiB 63.8% 2113 2.1KiB 19.4% mitogen.sudo 12089 11.8KiB 5924 5.8KiB 49.0% 2249 2.2KiB 18.6% mitogen.select 12325 12.0KiB 2929 2.9KiB 23.8% 964 0.9KiB 7.8% mitogen.service 41644 40.7KiB 22431 21.9KiB 53.9% 5886 5.7KiB 14.1% mitogen.fakessh 15599 15.2KiB 8011 7.8KiB 51.4% 2624 2.6KiB 16.8% mitogen.master 48733 47.6KiB 24570 24.0KiB 50.4% 6771 6.6KiB 13.9% ``` --- docs/changelog.rst | 1 + mitogen/parent.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 787dd1c4..9165dbda 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -21,6 +21,7 @@ To avail of fixes in an unreleased version, please download a ZIP file v0.3.1.dev0 (unreleased) ------------------------ +* :gh:issue:`774` Fix bootstrap failures on macOS 11.x and 12.x, involving Python 2.7 wrapper * :gh:issue:`834` Support for Ansible 3 and 4 (ansible-core 2.11) * :gh:issue:`869` Continuous Integration tests are now run with Tox * :gh:issue:`869` Continuous Integration tests now cover CentOS 6 & 8, Debian 9 & 11, Ubuntu 16.04 & 20.04 diff --git a/mitogen/parent.py b/mitogen/parent.py index 44ff9aba..c3efe28a 100644 --- a/mitogen/parent.py +++ b/mitogen/parent.py @@ -1412,9 +1412,12 @@ class Connection(object): # * macOS <= 10.14 (Darwin <= 18) install an unreliable Python version # switcher as /usr/bin/python, which introspects argv0. To workaround # it we redirect attempts to call /usr/bin/python with an explicit - # call to /usr/bin/python2.7. macOS 10.15+ (Darwin 19+) removed it. - # On these versions /usr/bin/python is a symlink to - # /System/Library/Frameworks/Python.framework/Versions/2.7/.../Python + # call to /usr/bin/python2.7. macOS 10.15 (Darwin 19) removed it. + # * macOS 11.x (Darwin 20, Big Sur) and macOS 12.x (Darwin 21, Montery) + # do something slightly different. The Python executable is patched to + # perform an extra execvp(). I don't fully understand the details, but + # setting PYTHON_LAUNCHED_FROM_WRAPPER=1 avoids it. + # * macOS 13.x (Darwin 22?) may remove python 2.x entirely. # # Locals: # R: read side of interpreter stdin. @@ -1437,7 +1440,8 @@ class Connection(object): os.close(r) os.close(W) os.close(w) - if sys.executable+sys.platform=='/usr/bin/pythondarwin'and os.uname()[2]<'19':sys.executable+='2.7' + if os.uname()[0]=='Darwin'and os.uname()[2][:2]<'19'and sys.executable=='/usr/bin/python':sys.executable='/usr/bin/python2.7' + if os.uname()[0]=='Darwin'and os.uname()[2][:2]in'2021'and sys.version[:3]=='2.7':os.environ['PYTHON_LAUNCHED_FROM_WRAPPER']='1' os.environ['ARGV0']=sys.executable os.execl(sys.executable,sys.executable+'(mitogen:CONTEXT_NAME)') os.write(1,'MITO000\n'.encode())