2017-01-09 37 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