Skip to content

Commit

Permalink
Add method to automatically clean up after an action plugin (ansible#…
Browse files Browse the repository at this point in the history
…65509)

* Use correct var, move cleanup for async
* Add changelog and tests. Fixes ansible#65393. Fixes ansible#65277.
* Kill off all long running async tasks from listen_ports_facts
* Update task to work with older jinja2
  • Loading branch information
sivel authored and anshulbehl committed Dec 10, 2019
1 parent 1879b76 commit da39b94
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 1 deletion.
7 changes: 7 additions & 0 deletions changelogs/fragments/action-plugin-always-cleanup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bugfixes:
- ActionBase - Add new ``cleanup`` method that is explicitly run by the
``TaskExecutor`` to ensure that the shell plugins ``tmpdir`` is always
removed. This change means that individual action plugins need not be
responsible for removing the temporary directory, which ensures that
we don't have code paths that accidentally leave behind the temporary
directory.
3 changes: 3 additions & 0 deletions lib/ansible/executor/task_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,8 @@ def _execute(self, variables=None):
return dict(failed=True, msg=to_text(e))
except AnsibleConnectionFailure as e:
return dict(unreachable=True, msg=to_text(e))
finally:
self._handler.cleanup()
display.debug("handler run complete")

# preserve no log
Expand Down Expand Up @@ -853,6 +855,7 @@ def _poll_async_result(self, result, templar, task_vars=None):
else:
return dict(failed=True, msg="async task produced unparseable results", async_result=async_result)
else:
async_handler.cleanup(force=True)
return async_result

def _get_become(self, name):
Expand Down
12 changes: 12 additions & 0 deletions lib/ansible/plugins/action/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ def run(self, tmp=None, task_vars=None):

return result

def cleanup(self, force=False):
"""Method to perform a clean up at the end of an action plugin execution
By default this is designed to clean up the shell tmpdir, and is toggled based on whether
async is in use
Action plugins may override this if they deem necessary, but should still call this method
via super
"""
if force or not self._task.async_val:
self._remove_tmp_path(self._connection._shell.tmpdir)

def get_plugin_option(self, plugin, option, default=None):
"""Helper to get an option from a plugin without having to use
the try/except dance everywhere to set a default
Expand Down
6 changes: 6 additions & 0 deletions test/integration/targets/listen_ports_facts/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,9 @@
assert:
that: 5555 in ansible_facts.udp_listen | map(attribute='port') | sort | list
when: (ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 7) or ansible_os_family == "Debian"

- name: kill all async commands
command: "kill -9 {{ item.pid }}"
loop: "{{ [tcp_listen, udp_listen]|flatten }}"
when: item.name == 'nc'
ignore_errors: true
29 changes: 29 additions & 0 deletions test/integration/targets/remote_tmp/playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,32 @@
- name: clean up test user
user: name=tmptest state=absent
become_user: root

- name: Test tempdir is removed
hosts: testhost
gather_facts: false
tasks:
- file:
state: touch
path: "/{{ output_dir }}/65393"

- copy:
src: "/{{ output_dir }}/65393"
dest: "/{{ output_dir }}/65393.2"
remote_src: true

- find:
path: "~/.ansible/tmp"
use_regex: yes
patterns: 'AnsiballZ_.+\.py'
recurse: true
register: result

- debug:
var: result

- assert:
that:
# Should only be AnsiballZ_find.py because find is actively running
- result.files|length == 1
- result.files[0].path.endswith('/AnsiballZ_find.py')
2 changes: 1 addition & 1 deletion test/integration/targets/remote_tmp/runme.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

set -ux

ansible-playbook -i ../../inventory playbook.yml -v "$@"
ansible-playbook -i ../../inventory playbook.yml -e "output_dir=${OUTPUT_DIR}" -v "$@"

0 comments on commit da39b94

Please sign in to comment.