Register variable in ansible and using custom filter in when

1.9k views Asked by At

I want to extract file only when particular directory do not exist.I wrote below code to achieve this.

- name: check if program already exists.
  shell: ls /tomcats|grep akash
  register: programexists
- name: extract archive
  command: chdir=/tomcats/ /bin/tar xvf  program.tar.gz
  when: programexists.stdout == {{ program }}

but this code fails when "akash" directory do not exists as programexits.stdout will be empty in that case.

I wonder if i can create a custom filter in filter_plugins which checks if directory exists and use the same in play book like

code for custom filter

__author__ = 'akthakur'
import os
class FilterModule(object):
    ''' Custom filters are loaded by FilterModule objects '''

    def filters(self):
        ''' FilterModule objects return a dict mapping filter names to
            filter functions. '''
        return {
            'directory_exists': self.directory_exists,
        }

    def directory_exists(self,program):
        static_location='/usr/local/tomcats'
        path=os.path.join(static_location,program)
        if os.path.isdir(path):
            return True
        else:
            return False

and use the filter like

- name: extract archive
  command: chdir=/tomcats/ /bin/tar xvf  program.tar.gz
  when: {{ 'akash'|directory_exists }}

I may be expecting too much from ansible but if some one can help me...i will be really thankful.

4

There are 4 answers

3
udondan On

It should be even simpler. The command module has a creates parameter, which is nothing but a filter and only will execute the command if the path given to creates does not exist. So if your command will create /tomcats/akash this should work:

- name: extract archive
  command: chdir=/tomcats/ /bin/tar xvf  program.tar.gz
  creates: /tomcats/akash
0
Antonis Christofides On

A custom filter would be overkill. There is an ignore_errors parameter.

- name: check if program already exists.
  shell: ls /tomcats|grep akash
  register: programexists
  ignore_errors: True
  always_run: True
  changed_when: False

- name: extract archive
  command: chdir=/tomcats/ /bin/tar xvf  program.tar.gz
  when: programexists.stdout == {{ program }}

It may also be better to use programexists.rc == 0 as the condition, in which case the command can become simply ls /tomcats/akash.

0
airdata On

There are a couple of syntax issues in the when condition.

Here's an updated version of your code:

- name: Check if program already exists
  command: ls /tomcats | grep akash
  register: programexists
  changed_when: false  # Do not mark the task as changed based on the output

- name: Extract archive
  command: tar xvf /tomcats/program.tar.gz -C /tomcats/
  args:
    chdir: /tomcats/
  when: "'{{ program }}' not in programexists.stdout_lines"
0
BTakacs On

If you want to achieve the riginal goal there is an 'unarchive' module (http://docs.ansible.com/ansible/unarchive_module.html). You can use it like this:

- name: unarchive if it does not exist
  unarchive: >
     src=program.tar.gz
     dest=/tomcats/
     creates=/tomcats/

The last parameter will check whether the directory exists and will skip the command if yes.