AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 831880
Accepted
Peter Turner
Peter Turner
Asked: 2017-02-11 10:18:28 +0800 CST2017-02-11 10:18:28 +0800 CST 2017-02-11 10:18:28 +0800 CST

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

  • 772

我正在运行 Ansible 2.0,我可以只运行它,但我也可能被我的经验测试欺骗相信一些不正确的东西,而且我找不到任何文档告诉我什么时候应该运行处理程序。

如果处理程序在任务结束时没有运行,这就是我的难题。我有一本包含 5 个角色的剧本,我想在末尾添加一个 6 个角色,该角色需要在开始之前完成第 4 个角色的处理程序。

有没有办法运行 Ansible 以在执行其他操作之前依赖处理程序完成(即角色完全完成),还是我使用处理程序错误?

ansible
  • 2 2 个回答
  • 18255 Views

2 个回答

  • Voted
  1. Best Answer
    techraf
    2017-02-11T15:59:25+08:002017-02-11T15:59:25+08:00

    处理程序被执行:

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

    因此,“要在需要具有第 4 个角色的处理程序的末尾添加一个 6 个角色”,您需要:

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

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

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


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

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

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


    • 经验证明(运行此 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"
      
    • 19
  2. Jacob Evans
    2017-02-11T21:19:19+08:002017-02-11T21:19:19+08:00

    处理程序是任务列表,与常规任务没有任何不同,由全局唯一名称引用,并由通知程序通知。如果没有通知处理程序,它将不会运行。无论有多少任务通知处理程序,它都只会运行一次,在特定播放中所有任务完成后。可靠的文档

    1)做同样事情的处理程序应该命名相同。
    restart nginx总是重新启动 nginx,而handler1不是handler2

    2)处理程序在整个“播放”的末尾运行,播放范围为您的部分。

    3)我会使用registerandwhen函数来处理应该重新启动的任务,注意这个 var 应该随身携带。

    代码源

    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 服务器进行多次更改。

    • 4

相关问题

  • 重复的 Ansible 任务

  • 无法形成站点中的文件的链接,该链接可用于使用 ansible 在远程服务器中启用的目录站点?

  • 如何执行 ansible 的特定角色?

  • Ansible 和 rbash

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve