Ansible通知另一个角色中的处理程序

Ansible通知另一个角色中的处理程序,ansible,ansible-playbook,Ansible,Ansible Playbook,我可以通知另一个角色的处理程序吗?我该怎么做才能让ansible找到它 用例是,例如,我想配置一些服务,然后在更改后重新启动它。不同的操作系统可能需要编辑不同的文件,甚至文件格式也可能不同。所以我想把它们放在不同的角色中(因为文件格式可以不同,不能通过设置组变量来完成)。但是重新启动服务的方法是相同的,使用service模块;因此,我想将处理程序设置为common角色 到底是为了实现这一目标吗?谢谢。如果包含处理程序文件,您应该能够做到这一点 例如: handlers: - include:

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

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


到底是为了实现这一目标吗?谢谢。

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

例如:

handlers:
  - include: someOtherRole/handlers/main.yml 
但我认为它并不优雅

一种更优雅的方式是让一部戏同时管理两个角色,如下所示:

- hosts: all
  roles:
  - role1
  - role2
- import_tasks: roles/OtherRole/handlers/main.yml
这将使两个角色都能够调用其他处理程序

但我再次建议将其全部放在一个角色和单独的文件中,并使用条件include


希望对您有所帮助,您也可以调用依赖角色的处理程序。可能比仅仅为了角色之间的关系而在剧本中包含文件或明确列出角色更简洁。例如:

  • 角色/my handlers/handlers/main.yml

    ---
    - name: nginx restart
      service: >
        name=nginx
        state=restarted
    
    ---
    - copy: >
        src=nginx.conf
        dest=/etc/nginx/
      notify: nginx restart
    
  • 角色/my other/meta/main.yml

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

    ---
    - name: nginx restart
      service: >
        name=nginx
        state=restarted
    
    ---
    - copy: >
        src=nginx.conf
        dest=/etc/nginx/
      notify: nginx restart
    

我也有类似的问题,但需要在其他依赖角色中采取许多行动

因此,我们没有调用handler,而是设定了这样一个事实:

- 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

您可以使用
import\u tasks
YourRole/handlers/main.yml
文件导入其他处理程序

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

- hosts: all
  roles:
  - role1
  - role2
- import_tasks: roles/OtherRole/handlers/main.yml
当然,
roles/MyRole/handlers/main.yml
也可能包括其他处理程序


这样,如果我想运行
MyRole
而不运行
OtherRole
中的任务,ansible将能够正确导入和运行
OtherRole
中的处理程序。目前我使用的是ansible v2.10.3,它支持在不同的角色上调用
处理程序。这是因为
处理程序
在游戏级别上是可见的,如所说。您可以在最下面的点中看到提到的文档

处理程序具有播放范围,因此可以在定义它们的角色之外使用

仅供参考,我对解决方案进行了测试,即调用其他角色的
处理程序
,效果良好!无需导入或其他,只需确保角色处于相同的剧本执行中

举例说明:

  • roles/vm/handlers/main.yaml

    ---
    - name: rebootvm
      ansible.builtin.reboot:
        reboot_timeout: 600
        test_command: whoami
    
    ---
    - name: Copy files from local to remote
      ansible.builtin.copy:
        dest: /home/ubuntu/config.conf
        src: config.conf
        backup: yes
        force: yes
      notify:
        - rebootvm
    
  • roles/config files/tasks/main.yaml

    ---
    - name: rebootvm
      ansible.builtin.reboot:
        reboot_timeout: 600
        test_command: whoami
    
    ---
    - 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支持这个的确切版本


编辑:代码缩进修复

你找到解决方案了吗?对我不起作用。我尝试了ansible playbook
v1.9.0.1
。不幸的是,即使在2.0版中,处理事件的能力也严重受损。我已经在这方面填补了一些错误:o(包含处理程序的操作不做任何事情,即使文件不存在也会保持沉默)o(ansible 2.0 yum和dnf modules不触发通知)o(on notify不检查处理程序存在)这是一个很好的方法。如果明确提到依赖角色包含其处理程序,这里的文档()将更有帮助。这也将运行在
my_handlers
role中定义的任务。我已经将role1作为role2的依赖项,但我无法从role2中触发role1的处理程序。我得到错误:“请求的处理程序…在主处理程序列表或侦听处理程序列表中都找不到”。无需设置事实,通过
寄存器设置的变量与事实具有相同的生存期。@LukeAntins通过寄存器设置的变量通过模块认为有用的任何“cruft”。将定义的变量设置为已知值更容易预测。它将您的playbook与特定模块实现分离,并与使用特定模块生成变量分离。在2.6.12上,处理程序不是隐式共享的。至少在我的例子中,在2014年的用户mpdehaan中,“可以毫无问题地定义两次处理程序,例如“重新启动apache”,系统将采用最新的定义”。但是,我的测试(Ansible 2.9.4)表明,如果定义了不同角色的处理程序,它们都会运行,但是如果只定义了一次,即使是在不同的角色中,它们也会运行,因为它们是全局的。不需要从另一个角色导入处理程序。