2017-01-09 39 views
1

我想在整個劇本中只運行一次處理程序。只爲整個劇本運行一次Ansible處理程序一次

我嘗試使用包括在劇本文件下面的語句,但是這導致在處理程序被運行多次,一次爲每個玩法:

- name: Configure common config 
    hosts: all 
    become: true 
    vars: 
     OE: "{{ ansible_hostname[5] }}" 
    roles: 
    - { role: common } 
    handlers: 
    - include: handlers/main.yml 

- name: Configure metadata config 
    hosts: metadata 
    become: true 
    vars: 
     OE: "{{ ansible_hostname[5] }}" 
    roles: 
    - { role: metadata } 
    handlers: 
    - include: handlers/main.yml 

這裏是處理器/主要的內容。陽明:

- name: restart autofs 
    service: 
    name: autofs.service 
    state: restarted 

這裏的任務之一的一個例子,通知處理程序:

- name: Configure automount - /opt/local/xxx in /etc/auto.direct 
    lineinfile: 
    dest: /etc/auto.direct 
    regexp: "^/opt/local/xxx" 
    line: "/opt/local/xxx -acdirmin=0,acdirmax=0,rdirplus,rw,hard,intr,bg,retry=2 nfs_server:/vol/xxx" 
    notify: restart autofs 

如何讓劇本僅在整個劇本中執行一次處理程序?

+0

您的playbook看起來有點瘋狂。這個劇本的總體思路是什麼?爲什麼你在這裏包括處理器?處理程序應該由任務通知,因此它是角色的一部分。 查看文檔如何使用處理程序:https://docs.ansible.com/ansible/playbooks_intro.html。 另一種只運行一次特定任務的方法如下:https://docs.ansible.com/ansible/playbooks_delegation.html#run-once –

+0

不確定wild是什麼意思。劇本是一系列戲劇,其中有兩個例子。我想爲多個播放使用單個處理程序,併爲整個Playbook執行一次。我希望這是有道理的。不需要只運行一次任務,只需要運行一次處理程序。 – user3155618

+0

@techraf劇中有多個任務通知處理程序。我編輯了問題並添加了其中一項任務。 – user3155618

回答

4

標題問題的文字回答是:不。然而,解決問題的方法是可能的,儘管它使用了額外的遊戲,而不是「劇本處理程序」(見下文)。

答案

儘管Ansible文檔聲稱劇本長介紹筆記是業務流程的基礎上,劇本是在現實中只是一個劇目的名單。

劇本沒有命名空間,沒有變量,沒有狀態。所有的配置,邏輯,任務都包含在遊戲中。

處理程序是另一方面,具有不同的調用計劃的任務(不是順序的,但有條件的,在末尾或在meta: flush_handlers)。

處理程序因此屬於一個遊戲,而不是一個劇本。


解決方案

也就是說,解決每一次劇本重新啓動服務的問題,可以使用內存庫存來解決。

你可以把從你的問題的處理到一個單獨的遊戲,並將其放置在劇本的結尾:

- hosts: hosts_to_restart_autofs 
    tasks: 
    - name: Perform autofs restart 
     service: 
     name: autofs.service 
     state: restarted 

然後使用處理程序中的每個發揮主機添加到hosts_to_restart_autofs列表與add_host module

handlers: 
    - name: restart autofs 
    add_host: 
     name: "{{ inventory_hostname }}" 
     groups: hosts_to_restart_autofs 

這樣的處理程序,而不是直接在目標節點上重新啓動該服務,將是節點的主機名,而不是添加到內存中的庫存。如果第二次播放也會導致通知處理程序,則主機名已經在列表中。

上次播放將執行任務以重新啓動由多個播放中的處理程序添加到列表中的目標節點上的服務。

+0

謝謝@techraf!答案是有用的,解決方案在測試時工作。 – user3155618

0

我不清楚你的處理程序應該做什麼。無論如何,對於official documentation,處理程序

在任務的每個塊的在比賽結束觸發, 並將只能觸發一次,即使多個不同的 任務通知[...]作爲的Ansible 2.2,處理程序也可以「傾聽」通用主題,任務可以通知這些主題如下:

因此,處理程序會針對每個任務塊通知/執行一次。 可能你只是在「所有」目標主機之後保持處理程序的目標,但它似乎不是乾淨利用處理程序。 。

+0

如果處理程序僅包含在「所有」目標主機的播放中,則在其他遊戲中通知時不會運行。 – user3155618

+0

你說得對。但是你的「handlers/main.yml」在做什麼? – gile

+0

編輯原始問題,請在帖子中查看「handlers/main.yml」的內容。 – user3155618