Reputation: 265
I have an ansible playbook to kill running processes and works great most of the time!, however, from time to time we find processes that just can't be killed so, "wait_for" gets to the timeout, throws an error and it stops the process.
The current workaround is to manually go into the box, use "kill -9" and run the ansible playbook again so I was wondering if there is any way to handle this scenario from ansible itself?, I mean, I don't want to use kill -9 from the beginning but I maybe a way to handle the timeout?, even to use kill -9 only if process hasn't been killed in 300 seconds? but what would be the best way to do it?
These are the tasks I currently have:
- name: Get running processes
shell: "ps -ef | grep -v grep | grep -w {{ PROCESS }} | awk '{print $2}'"
register: running_processes
- name: Kill running processes
shell: "kill {{ item }}"
with_items: "{{ running_processes.stdout_lines }}"
- name: Waiting until all running processes are killed
wait_for:
path: "/proc/{{ item }}/status"
state: absent
with_items: "{{ running_processes.stdout_lines }}"
Thanks!
Upvotes: 25
Views: 71090
Reputation: 1
This Code Worked for me
- hosts: ubuntu
become: yes
tasks:
- name: Get Apache PIDs
shell:
cmd: ps -ef | grep -v grep | grep -w apache2 | awk '{print $2}' | awk 'FNR == 1 {print}'
warn: false
changed_when: false
check_mode: false
register: apache_pids
- name: Kill running processes
shell: "kill {{ item }}"
with_items:
- "{{ apache_pids.stdout_lines }}"
- name: Show PIDs
debug:
var: apache_pids
Upvotes: 0
Reputation: 51
After some investigations and struggling with ansible_linter
, below an alternative way (eg. without use of ignore_error
)
- name: "disable and stop PROCESS"
service:
name: PROCESS
enabled: no
state: stopped
tags:
- stop
- name: "evaluate running PROCESS processes from remote host"
command: "/usr/bin/pgrep PROCESS"
register: running_PROCESS
failed_when: running_PROCESS.rc > 1
changed_when:
- running_PROCESS.rc == 0
tags:
- stop
- name: "pkill PROCESS running processes"
command: "/usr/bin/pkill PROCESS"
register: kill_PROCESS
changed_when: kill_PROCESS.rc == 0
when: running_PROCESS.stdout_lines | length > 0
tags:
- stop
- name: "check PROCESS processes"
wait_for:
path: "/proc/{{ item }}/status"
state: absent
with_items: "{{ running_PROCESS.stdout_lines }}"
when: running_PROCESS.stdout_lines | length > 0
tags:
- stop
- name: "force kill stuck PROCESS processes"
command: "/usr/bin/pkill -9 PROCESS"
register: kill9_PROCESS
changed_when: kill9_PROCESS.rc == 0
failed_when: kill9_PROCESS.rc > 1
when:
- running_PROCESS.stdout_lines | length > 0
tags:
- stop
Upvotes: 4
Reputation: 4644
The killall
command has a wait option that might be useful.
Install psmisc:
tasks:
- apt: pkg=psmisc state=present
Then use killall like this:
tasks:
- shell: "killall screen --wait"
ignore_errors: true # In case there is no process
-w, --wait
:
Wait for all killed processes to die. killall checks once per second if any of the killed processes still exist and only returns if none are left.
Upvotes: 5
Reputation: 4513
You could ignore errors on wait_for
and register the result to force kill failed items:
- name: Get running processes
shell: "ps -ef | grep -v grep | grep -w {{ PROCESS }} | awk '{print $2}'"
register: running_processes
- name: Kill running processes
shell: "kill {{ item }}"
with_items: "{{ running_processes.stdout_lines }}"
- wait_for:
path: "/proc/{{ item }}/status"
state: absent
with_items: "{{ running_processes.stdout_lines }}"
ignore_errors: yes
register: killed_processes
- name: Force kill stuck processes
shell: "kill -9 {{ item }}"
with_items: "{{ killed_processes.results | select('failed') | map(attribute='item') | list }}"
Upvotes: 65