简体   繁体   中英

With Ansible what is the best way of remembering a command has executed successfully previously?

With the command module , if the command creates a file, you can check to see if that file exists. If it does it prevents the command executing again.

- command: touch ~/myfile
  args:
    creates: ~/myfile

However, if the command does not create a file then on a re-run it executes again.

To avoid a second execution, I create some random file on a change (notify) as follows:

- command: dothisonceonly # this does not create a file
  args:
    creates: ~/somefile
  notify: done

then the handler:

- name: done
  command: touch ~/somefile

This approach works but is a bit ugly. Can anyone shed let on best practice? Maybe setting some fact? Maybe a whole new approach?

It is a fact (in common language) that a command was run successfully on a specific target host, so the most appropriate would be to use local facts (in Ansible vernacular).

In your handler save the state as a JSON file under /etc/ansible/facts.d with copy module and content parameter.

It will be retrieved and accessible whenever you run a play against the host with a regular fact-gathering process.

Then you can control the tasks with when condition (you need to include the default filter for the situation when no fact exists yet).

Ideally with Ansible, check for the state that was changed by the first command rather than using a file as a proxy. The reason being that checking the actual state of something provides better immutability since it is tested on every pass.

If there is a reason not to use that approach. Then register the result of the command and use that instead of a notifier to trigger creation of the file.

- command: dothisonceonly # this does not create a file
  creates: ~/somefile
  register: result

- file:
    path: ~/somefile
    state: touch
  when: result|succeeded

If you are curious to see what is happening here, add:

- debug: var=result

Be aware with notifiers that they are run at the end of the play. This means that if a notifier is triggered by a task but then then play fails to complete, the notifier will not be run. Conversely there are Ansible options which cause notifiers to run even when not triggered by tasks.

This is my actual implementation based on the answer by @techraf

- command: echo 'phew'
  register: itworks
  notify: Done itworks
  when: ansible_local.itworks | d(0) == 0

and handler:

- name: Done itworks
  copy:
    content: '{{ itworks }}'
    dest: /etc/ansible/facts.d/itworks.fact

Docs:

http://docs.ansible.com/ansible/playbooks_variables.html#local-facts-facts-d

Thanks @techraf this works great and persists facts.

EDIT

Applied default value logic in @techraf's comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM