Skip to content

Commit 94a6e4b

Browse files
committed
Allow using temporary directories on filesystems mounted noexec
Neither Ansible nor Mitogen need the temporary directory to be executable. Allow using noexec temporary directories so that mitogen-ansible can be used in environments where unpriviledged users are not allowed to have directories both writable and executable. Binary Ansible modules require the temporary directory to be executable. It's up to the user to make sure Ansible and their environement are configured correctly for this use case. Fixes #632.
1 parent c9071d7 commit 94a6e4b

4 files changed

Lines changed: 11 additions & 28 deletions

File tree

ansible_mitogen/target.py

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@
7272

7373
MAKE_TEMP_FAILED_MSG = (
7474
u"Unable to find a useable temporary directory. This likely means no\n"
75-
u"system-supplied TMP directory can be written to, or all directories\n"
76-
u"were mounted on 'noexec' filesystems.\n"
75+
u"system-supplied TMP directory can be written to.\n"
7776
u"\n"
7877
u"The following paths were tried:\n"
7978
u" %(paths)s\n"
@@ -269,21 +268,11 @@ def is_good_temp_dir(path):
269268
return False
270269

271270
try:
272-
try:
273-
os.chmod(tmp.name, int('0700', 8))
274-
except OSError:
275-
e = sys.exc_info()[1]
276-
LOG.debug('temp dir %r unusable: chmod failed: %s', path, e)
277-
return False
278-
279-
try:
280-
# access(.., X_OK) is sufficient to detect noexec.
281-
if not os.access(tmp.name, os.X_OK):
282-
raise OSError('filesystem appears to be mounted noexec')
283-
except OSError:
284-
e = sys.exc_info()[1]
285-
LOG.debug('temp dir %r unusable: %s', path, e)
286-
return False
271+
os.chmod(tmp.name, int('0700', 8))
272+
except OSError:
273+
e = sys.exc_info()[1]
274+
LOG.debug('temp dir %r unusable: chmod failed: %s', path, e)
275+
return False
287276
finally:
288277
tmp.close()
289278

@@ -294,8 +283,8 @@ def find_good_temp_dir(candidate_temp_dirs):
294283
"""
295284
Given a list of candidate temp directories extracted from ``ansible.cfg``,
296285
combine it with the Python-builtin list of candidate directories used by
297-
:mod:`tempfile`, then iteratively try each until one is found that is both
298-
writeable and executable.
286+
:mod:`tempfile`, then iteratively try each until one is found that is
287+
writeable.
299288
300289
:param list candidate_temp_dirs:
301290
List of candidate $variable-expanded and tilde-expanded directory paths

docs/ansible_detailed.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,7 @@ interpreter, its location is consistent for each account, and it is always
541541
privately owned by that account.
542542

543543
During startup, the persistent remote interpreter tries the paths below until
544-
one is found that is writeable and lives on a filesystem with ``noexec``
545-
disabled:
544+
one is found that is writeable:
546545

547546
1. ``$variable`` and tilde-expanded ``remote_tmp`` setting from
548547
``ansible.cfg``

docs/changelog.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ In progress (unreleased)
2727
* :gh:issue:`1499` tests: Run Mitogen unittests without
2828
``MITOGEN_LOG_LEVEL=debug``
2929
* :gh:issue:`1505` CI: Upgrade to GitHub Actions runners that use Node 24
30-
30+
* :gh:issue:`1498` :mod:`ansible_mitogen`: Allow using temporary directories on
31+
filesystems mounted noexec
3132

3233
v0.3.45 (2026-03-30)
3334
--------------------

tests/ansible/tests/target_test.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,3 @@ def test_weird_filesystem(self, os_chmod):
100100
os_chmod.side_effect = OSError('nope')
101101
with NamedTemporaryDirectory() as temp_path:
102102
self.assertFalse(self.func(temp_path))
103-
104-
@mock.patch('os.access')
105-
def test_noexec(self, os_access):
106-
os_access.return_value = False
107-
with NamedTemporaryDirectory() as temp_path:
108-
self.assertFalse(self.func(temp_path))

0 commit comments

Comments
 (0)