issue #397: fix another case where stray tmpdirs can be left behind.

Newer Ansibles use atexit.register() to invoke cleanup, so we need to
run those registrations after each run.
issue260
David Wilson 6 years ago
parent 1b17aa1d1a
commit 7fd9fb0014

@ -38,6 +38,7 @@ how to build arguments for it, preseed related data, etc.
from __future__ import absolute_import from __future__ import absolute_import
from __future__ import unicode_literals from __future__ import unicode_literals
import atexit
import ctypes import ctypes
import errno import errno
import imp import imp
@ -757,9 +758,25 @@ class NewStyleRunner(ScriptRunner):
if klass and isinstance(exc, klass): if klass and isinstance(exc, klass):
mod.module.fail_json(**exc.results) mod.module.fail_json(**exc.results)
def _run(self): def _run_code(self, code, mod):
code = self._get_code() try:
if mitogen.core.PY3:
exec(code, vars(mod))
else:
exec('exec code in vars(mod)')
except Exception as e:
self._handle_magic_exception(mod, e)
raise
def _run_atexit_funcs(self):
"""
Newer Ansibles use atexit.register() to trigger tmpdir cleanup, when
AnsibleModule.tmpdir is responsible for creating its own temporary
directory.
"""
atexit._run_exitfuncs()
def _run(self):
mod = types.ModuleType(self.main_module_name) mod = types.ModuleType(self.main_module_name)
mod.__package__ = None mod.__package__ = None
# Some Ansible modules use __file__ to find the Ansiballz temporary # Some Ansible modules use __file__ to find the Ansiballz temporary
@ -771,16 +788,13 @@ class NewStyleRunner(ScriptRunner):
'ansible_module_' + os.path.basename(self.path), 'ansible_module_' + os.path.basename(self.path),
) )
code = self._get_code()
exc = None exc = None
try: try:
try: try:
if mitogen.core.PY3: self._run_code(code, mod)
exec(code, vars(mod)) finally:
else: self._run_atexit_funcs()
exec('exec code in vars(mod)')
except Exception as e:
self._handle_magic_exception(mod, e)
raise
except SystemExit as e: except SystemExit as e:
exc = e exc = e

@ -1,3 +1,4 @@
- import_playbook: atexit.yml
- import_playbook: builtin_command_module.yml - import_playbook: builtin_command_module.yml
- import_playbook: custom_bash_hashbang_argument.yml - import_playbook: custom_bash_hashbang_argument.yml
- import_playbook: custom_bash_old_style_module.yml - import_playbook: custom_bash_old_style_module.yml
@ -15,6 +16,6 @@
- import_playbook: environment_isolation.yml - import_playbook: environment_isolation.yml
- import_playbook: etc_environment.yml - import_playbook: etc_environment.yml
- import_playbook: forking_active.yml - import_playbook: forking_active.yml
- import_playbook: forking_inactive.yml
- import_playbook: forking_correct_parent.yml - import_playbook: forking_correct_parent.yml
- import_playbook: forking_inactive.yml
- import_playbook: missing_module.yml - import_playbook: missing_module.yml

@ -0,0 +1,31 @@
# issue #397: newer Ansibles rely on atexit to cleanup their temporary
# directories. Ensure atexit handlers run during runner completion.
- name: integration/runner/atexit.yml
hosts: test-targets
gather_facts: false
any_errors_fatal: false
tasks:
#
# Verify a run with a healthy atexit handler. Broken handlers cause an
# exception to be raised.
#
- custom_python_run_script:
script: |
import atexit
atexit.register(lambda:
open('/tmp/atexit-was-triggered', 'w').write('yep'))
- slurp:
path: /tmp/atexit-was-triggered
register: out
- assert:
that:
- out.content|b64decode == "yep"
- file:
path: /tmp/atexit-was-triggered
state: absent
Loading…
Cancel
Save