diff --git a/ansible_mitogen/runner.py b/ansible_mitogen/runner.py index f5cb1283..c9ab8427 100644 --- a/ansible_mitogen/runner.py +++ b/ansible_mitogen/runner.py @@ -59,6 +59,19 @@ ansible.module_utils.basic._ANSIBLE_ARGS = '{}' LOG = logging.getLogger(__name__) +def reopen_readonly(fp): + """ + Replace the file descriptor belonging to the file object `fp` with one + open on the same file (`fp.name`), but opened with :py:data:`os.O_RDONLY`. + This enables temporary files to be executed on Linux, which usually theows + ``ETXTBUSY`` if any writeable handle exists pointing to a file passed to + `execve()`. + """ + fd = os.open(fp.name, os.O_RDONLY) + os.dup2(fd, fp.fileno()) + os.close(fd) + + class Runner(object): """ Ansible module runner. After instantiation (with kwargs supplied by the @@ -189,6 +202,7 @@ class ProgramRunner(Runner): self.program_fp.write(self._get_program()) self.program_fp.flush() os.chmod(self.program_fp.name, int('0700', 8)) + reopen_readonly(self.program_fp) def _get_program(self): """ @@ -244,6 +258,7 @@ class ArgsFileRunner(Runner): ) self.args_fp.write(self._get_args_contents()) self.args_fp.flush() + reopen_readonly(self.program_fp) def _get_args_contents(self): """