Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.2k views
in Technique[技术] by (71.8m points)

How can I perform ansible error-handling at playbook level?

I have a main playbook which imports other playbooks to perform actions in several machines. machine1 is a hub where test results are collected, after being executed on other machines:

- name: clear state
  import_playbook: playbook-clear-machines-state.yml
 
- name: prepare run
  hosts: machine1
  roles:
    - prepare_test_run
    
- name: run_tests_in_machine2
  import_playbook: playbook-run-tests-machine2.yml
  ignore_error: yes
  
  ...

What I would like to guarantee is that only an instance is running at a time (i.e. no one is able to run tests if an user is already doing so). I thought of using a lock file in machine1 as a way of preventing that, in the following manner:

- name: check temp file
  hosts: machine1
  tasks:
    - name: get stats of lock file
      stat:
        path: ./ansible.lock
      register: st
    - fail:
        msg: "tests already running"
      when:
        - st.stat.isreg is defined and st.stat.isreg
    - name: create lock file
      file:
        path: ./ansible.lock
        state: touch
        
- name: run all tests
  import_playbook: playbook-main.yml      
  ignore_errors: yes
  
- name: delete lock file
  hosts: machine1
  tasks:
    - name: delete ansible.lock file
      file:
        path: ./ansible.lock
        state: absent

The problem here is that I need to make sure the lock file is always deleted in the end - even if there was an error at an earlier play. How could I accomplish this? I tried to look into blocks and handlers but they don't seem appropriate to use at this level. Can anybody point me to a strategy/way to accomplish this?

Many thanks, José.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For this needs, you have rescue and always mechanism that must corresponding to your use case. You have more details here.

So with your example code, this must looks like this :

- name: check temp file
  hosts: machine1
  tasks:
    - name: get stats of lock file
      stat:
        path: ./ansible.lock
      register: st
    - fail:
        msg: "tests already running"
      when:
        - st.stat.isreg is defined and st.stat.isreg
    - name: run all tests
      block:
        - name: create lock file
          file:
            path: ./ansible.lock
            state: touch
        - name: 'playbook-main.yml'
          # import_playbook: playbook-main.yml
          # Paste the content of this playbook here
          ignore_errors: yes
      always:
        - name: delete lock file
          file:
            path: ./ansible.lock
            state: absent

In a context really close to you, you have this reponse to.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...