【问题标题】:Ansible notify handlers in another role另一个角色的 Ansible 通知处理程序
【发布时间】:2014-05-04 04:00:06
【问题描述】:

我可以通知其他角色的处理程序吗?我应该怎么做才能让ansible找到它?

用例是,例如我想配置一些服务,然后在更改时重新启动它。不同的操作系统可能有不同的文件要编辑,甚至文件格式也可能不同。所以我想把它们放到不同的角色中(因为文件格式可以不同,不能通过设置group_vars来完成)。但是重启服务的方式是一样的,使用service模块;所以我想把处理程序放到common角色。

反正是要实现这个吗?谢谢。

【问题讨论】:

  • 你找到解决办法了吗?

标签: ansible ansible-playbook


【解决方案1】:

如果您包含处理程序文件,您应该能够做到这一点。

例子:

handlers:
  - include: someOtherRole/handlers/main.yml 

但我不认为它优雅。

一个更优雅的方法是让一个角色同时管理两个角色,像这样:

- hosts: all
  roles:
  - role1
  - role2

这将使两个角色都能够调用其他处理程序。

但我再次建议将所有内容集中在一个角色中并单独文件并使用条件包含http://docs.ansible.com/playbooks_conditionals.html#conditional-imports

希望有帮助

【讨论】:

  • 在 2.6.12 处理程序不隐式共享。至少在我的情况下。
  • 2014年用户mpdehaansaid,“可以定义一个handler没有问题,比如“restart apache”,系统会采用最新的定义”。但是,我的测试(Ansible 2.9.4)表明,如果定义了不同角色的处理程序,它们运行,但如果它们只定义一次,即使在不同的角色中,它们仍然是运行,所以因为它们是全球性的。无需从其他角色导入处理程序。
【解决方案2】:

您还可以调用 依赖 角色的处理程序。可能比仅出于角色与角色关系的目的而在剧本中包含文件或明确列出角色更干净。例如:

  • roles/my-handlers/handlers/main.yml

    ---
    - name: nginx restart
      service: >
        name=nginx
        state=restarted
    
  • roles/my-other/meta/main.yml

    ---
    dependencies:
    - role: my-handlers
    
  • roles/my-other/tasks/main.yml

    ---
    - copy: >
        src=nginx.conf
        dest=/etc/nginx/
      notify: nginx restart
    

【讨论】:

  • 它对我不起作用。我尝试使用 ansible-playbook v1.9.0.1
  • 不幸的是,即使在 2.0 处理事件时也严重损坏。我已经填写了一些错误:o github.com/ansible/ansible/issues/11694(包含处理程序什么都不做,如果文件不存在,甚至保持沉默)o github.com/ansible/ansible/issues/11696(ansible 2.0 yum 和 dnf 模块不会触发通知)o github.com/ansible/ansible/issues/11766(打开通知未检查处理程序存在)
  • 这是一个很好的方法。如果明确提到依赖角色包含其处理程序,此处的文档 (docs.ansible.com/ansible/playbooks_roles.html#role-dependencies) 会更有帮助。
  • 这也将运行my_handlers角色中定义的任务。
  • 好吧,我将角色 1 作为角色 2 的依赖项,但我无法从角色 2 中触发角色 1 的处理程序。我收到错误消息:“在主处理程序列表和侦听处理程序列表中都找不到请求的处理程序......”。
【解决方案3】:

我遇到了类似的问题,但需要在其他相关角色中采取许多措施。

因此,与其调用处理程序 - 我们设置一个事实,如下所示:

- name: install mylib to virtualenv
  pip: requirements=/opt/mylib/requirements.txt virtualenv={{ mylib_virtualenv_path }}
  sudo_user: mylib
  register: mylib_wheel_upgraded

- name: set variable if source code was upgraded
  set_fact:
    mylib_source_upgraded: true
  when: mylib_wheel_upgraded.changed

然后在其他地方担任另一个角色:

- name: restart services if source code was upgraded
  command: /bin/true
  notify: restart mylib server
  when: mylib_source_upgraded

【讨论】:

  • 无需设置事实,通过register设置的变量与事实的寿命相同。
  • @LukeAntins 通过寄存器设置的变量会通过模块认为有用的任何“垃圾”。将您定义的变量设置为已知值更容易预测。它将您的剧本与特定模块实现以及使用特定模块生成变量分离。
【解决方案4】:

您可以使用import_tasksYourRole/handlers/main.yml 文件中导入其他处理程序。

所以,如果MyRole 需要在某些OtherRole 中调用处理程序,roles/MyRole/handlers/main.yml 将如下所示:

- import_tasks: roles/OtherRole/handlers/main.yml

当然roles/MyRole/handlers/main.yml 也可能包含其他处理程序。

这样,如果我想运行 MyRole 而不运行来自 OtherRole 的任务,ansible 将能够正确导入和运行来自 OtherRole 的处理程序

【讨论】:

    【解决方案5】:

    目前我正在使用 ansible v2.10.3,它支持在不同的角色上调用 handlers。这是因为handlers 在播放级别可见,正如Ansible Docs 所说。您可以在最底部看到提到的文档。

    处理程序是游戏范围的,因此可以在定义它们的角色之外使用。

    仅供参考,我测试了解决方案,即调用其他角色的handlers 并且它有效!无需导入,否则,只需确保角色在同一个剧本执行中

    举例说明:

    • roles/vm/handlers/main.yaml

      ---
      - name: rebootvm
        ansible.builtin.reboot:
          reboot_timeout: 600
          test_command: whoami
      
    • roles/config-files/tasks/main.yaml

      ---
      - name: Copy files from local to remote
        ansible.builtin.copy:
          dest: /home/ubuntu/config.conf
          src: config.conf
          backup: yes
          force: yes
        notify:
          - rebootvm
      

    因此,当配置文件(即config.conf)发生更改时,Ansible 会将其发送到远程位置并通知处理程序rebootvm,然后重新启动 VM。

    附:我不知道 Ansible 到底是什么版本支持这个。

    编辑:代码缩进修复

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      相关资源
      最近更新 更多