角色中定义的 Ansible 处理程序是否在整个剧本或角色之后运行?

角色中定义的 Ansible 处理程序是否在整个剧本或角色之后运行?

我正在运行 Ansible 2.0,我可以直接运行它,但是我也可能被我的经验测试所欺骗而相信一些不真实的东西,而且我找不到任何文档来告诉我何时应该运行处理程序。

如果处理程序在其任务结束时没有运行,这就是我的难题。我有一个包含 5 个角色的剧本,我想在最后添加一个第 6 个角色,它需要先完成第 4 个角色的处理程序才能启动。

有没有办法运行 Ansible 来依赖于处理程序的完成(即角色完全完成)然后再执行其他操作,或者我使用处理程序的方式错误?

答案1

处理程序执行如下:

  • 在戏剧(不是剧本)的结尾
  • meta: flush_handlers执行任务时

所以 ”在末尾添加第 6 个角色,该角色需要有第 4 个角色的处理程序“ 你需要:

  • 或者将角色分配分成单独的剧目;
  • 或者添加一个元任务并包含第 6 个角色include_role模块

    roles:
      - role4
    tasks:
      - meta: flush_handlers
      - include_role:
          name: role6
    

对于您的用例,我建议使用第一种方法,因为该include_role模块仍然很新,并且在使用时存在一些怪癖(请参阅这个问题)。


此外,请注意处理程序的名称和监听调用是全局的,因此,如果两个处理程序具有相同的名称并且在单个剧目中分配了两个角色,则处于不同角色的两个处理程序将发生冲突。(参考。处理程序:在更改时运行操作

处理程序 [ ] 由全局唯一名称引用,并由通知程序通知。[ ] 处理程序,它将只运行一次,在特定播放中的所有任务完成后。

处理程序名称和监听主题位于全局命名空间中。


  • 经验证明(运行此 shell 脚本来确认处理程序在剧本结束时执行 - 这里有矛盾的评论和答案):

    #!/bin/bash
    
    mkdir -p ./sf831880/roles/role1
    mkdir -p ./sf831880/roles/role1/handlers
    mkdir -p ./sf831880/roles/role1/tasks
    mkdir -p ./sf831880/roles/role2
    mkdir -p ./sf831880/roles/role2/handlers
    mkdir -p ./sf831880/roles/role2/tasks
    
    cat >./sf831880/roles/role1/tasks/main.yml <<TASKS1_END
    ---
    - name: Always true in role1
      command: echo role1
      notify: handler1
    TASKS1_END
    
    cat >./sf831880/roles/role2/tasks/main.yml <<TASKS2_END
    ---
    - name: Always true in role2
      command: echo role2
      notify: handler2
    TASKS2_END
    
    cat >./sf831880/roles/role1/handlers/main.yml <<HANDLERS1_END
    ---
    - name: handler1
      debug:
        msg: "This is a handler in role1"
    HANDLERS1_END
    
    cat >./sf831880/roles/role2/handlers/main.yml <<HANDLERS2_END
    ---
    - name: handler2
      debug:
        msg: "This is a handler in role2"
    HANDLERS2_END
    
    cat >./sf831880/playbook.yml <<PLAYBOOK_END
    ---
    - hosts: localhost
      gather_facts: no
      connection: local
      roles:
        - role1
        - role2
      tasks:
        - debug:
            msg: "This is a task in a play"
    PLAYBOOK_END
    
    ansible-playbook ./sf831880/playbook.yml
    

    结果:

    PLAY [localhost] ***************************************************************
    
    TASK [role1 : Always true in role1] ********************************************
    changed: [localhost]
    
    TASK [role2 : Always true in role2] ********************************************
    changed: [localhost]
    
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "msg": "This is a task in a play"
    }
    
    RUNNING HANDLER [role1 : handler1] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role1"
    }
    
    RUNNING HANDLER [role2 : handler2] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role2"
    
  • 游戏经过修改,包含meta: flush_handlers

    ---
    - hosts: localhost
      gather_facts: no
      connection: local
      roles:
        - role1
        - role2
      tasks:
        - meta: flush_handlers
        - debug:
            msg: "This is a task in a play"
    

    结果:

    PLAY [localhost] ***************************************************************
    
    TASK [role1 : Always true in role1] ********************************************
    changed: [localhost]
    
    TASK [role2 : Always true in role2] ********************************************
    changed: [localhost]
    
    RUNNING HANDLER [role1 : handler1] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role1"
    }
    
    RUNNING HANDLER [role2 : handler2] *********************************************
    ok: [localhost] => {
        "msg": "This is a handler in role2"
    }
    
    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "msg": "This is a task in a play"
    

答案2

处理程序是任务列表,与常规任务并无太大区别,它们由全局唯一名称引用,并由通知程序通知。如果没有通知处理程序,它将不会运行。无论有多少任务通知处理程序,它都只会在特定剧集中的所有任务完成后运行一次。ansible 文档

1) 执行相同操作的处理程序应使用相同的名称。
restart nginx始终重新启动 nginx,而handler1不是handler2

2) 处理程序在整个“播放”结束时运行,播放范围仅限于您的部分。

3)我会使用registerwhen需要重新启动的任务的功能,请注意此变量应该随身携带。

代码源

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Play 1"
}

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role2 : Run if change in task c of role 1] *******************************
changed: [localhost]

TASK [role2 : Always true in role2] ********************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "This is a task in a play"
}

RUNNING HANDLER [role1 : handler] **********************************************
ok: [localhost] => {
    "msg": "This is a handler in role1"
}

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Play 2"
}

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role1 : Always true in role1] ********************************************
changed: [localhost]

TASK [role2 : Run if change in task c of role 1] *******************************
changed: [localhost]

TASK [role2 : Always true in role2] ********************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "This is a task in a play"
}

RUNNING HANDLER [role1 : handler] **********************************************
ok: [localhost] => {
    "msg": "This is a handler in role1"
}

PLAY RECAP *********************************************************************
localhost                  : ok=20   changed=14   unreachable=0    failed=0

有很多方法可以完成相同的任务。处理程序旨在防止多次重新启动同一进程,例如对具有网站、ssl 证书和其他需要重新启动服务的任务的 nginx 服务器进行多次更改。

相关内容