Search code examples
ansibleruntime-errorkill

Perform task until the file gets deleted in Ansible


I will to fire the kill command until the file "/proc/pid/status" or folder "/proc/pid" gets deleted.

Below is my playbook for the same:

- name: Kill running processes

  shell: "kill -9 {{ item }}"
  retries: 5
  delay: 4
  until: "/proc/{{ item }}/status is exists"
  with_items: "{{ running_processes.stdout_lines }}"

However, my playbook fails with the below error.

TASK [Kill running processes] **************************************************
[1;30mtask path: /app/scripts/test.yml:182[0m
[1;35mdelimiters such as {{ }} or {% %}. Found: /proc/{{ item }}/status is exists[0m
[1;35m[0m
[0;31mfatal: [10.9.9.131]: FAILED! => {"msg": "The conditional check '/proc/{{ item }}/status is exists' failed. The error was: Invalid conditional detected: invalid syntax (<unknown>, line 1)"}[0m

I'm on the latest version of Ansible.

Can you please suggest what is the issue with my playbook code?


Solution

  • The error is "Invalid conditional detected", which is correct. You've written:

      until: "/proc/{{ item }}/status is exists"
    

    When you write a boolean expression like this, the syntax is:

    <value> is <test>
    

    Where <value> needs to be either a literal value (like a string, or a number) or a variable name. You have /proc/<some number>/status, which is none of those things. You could make the expression syntactically correct by quoting the /proc path, like this:

      until: "'/proc/{{ item }}/status' is exists"
    

    But there's still a problem: the condition is evaluated in an implic jinja2 templating context, which means you never use {{...}} markers (this is true for both until and when). Inside a templating context, you refer to variables by name only, and use string formatting or string concatenation to put them together with other strings. For example:

      until: "'/proc/%s/status' % item is exists"
    

    Or:

      until: "'/proc/{}/status'.format(item) is exists"
    

    Lastly, I think you mean is not exists, because you're killing a process and waiting for it to die.


    While the above gives you a syntactically correct conditional, it's important to note this bit from the Ansible documentation:

    Like all templating, tests always execute on the Ansible controller, not on the target of a task, as they test local data.

    If you are targeting a remote host, remember that the is exists task will execute on the host where you are running ansible, not on the remote host.