Обработчики уведомлений Ansible в другой роли

Могу ли я уведомить обработчика в другой роли? Что мне сделать, чтобы ансибль нашел его?

Пример использования, например, Я хочу настроить какую-то службу, а затем перезапустить ее, если она изменилась. В разных ОС, вероятно, есть разные файлы для редактирования, и даже формат файла может отличаться. Поэтому я хотел бы распределить их по разным ролям (поскольку формат файла может быть другим, этого нельзя сделать, установив group_vars). Но способ перезапуска службы тот же, с использованием модуля service; поэтому я хотел бы назначить обработчика common ролью.

В любом случае добиться этого? Спасибо.


person Kan Li    schedule 26.03.2014    source источник
comment
Вы нашли какое-нибудь решение?   -  person Robert    schedule 16.07.2014


Ответы (5)


Вы также можете вызывать обработчики роли зависимости. Может быть проще, чем включение файлов или явный список ролей в playbook только для целей отношения роли к роли. Например.:

  • роли / мои-обработчики / обработчики / main.yml

    ---
    - name: nginx restart
      service: >
        name=nginx
        state=restarted
    
  • роли / мой-другой / мета / main.yml

    ---
    dependencies:
    - role: my-handlers
    
  • роли / другие / задачи / main.yml

    ---
    - copy: >
        src=nginx.conf
        dest=/etc/nginx/
      notify: nginx restart
    
person famousgarkin    schedule 27.03.2015
comment
У меня это не работает. Я пробовал использовать ansible-playbook v1.9.0.1. - person dgellow; 10.04.2015
comment
К сожалению даже в 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 (при уведомлении не существует проверенного обработчика) - person Hubbitus; 28.07.2015
comment
Это отличный подход. Документы здесь (docs.ansible.com/ansible/playbooks_roles.html#role- dependencies) было бы более полезным, если бы было явно указано, что зависимые роли имеют свои обработчики. - person thisjustin; 22.10.2015
comment
При этом также будут выполняться задачи, определенные в роли my_handlers. - person mdh; 11.02.2017
comment
Ну, у меня роль1 как зависимость от role2, но я не могу запускать обработчики role1 из role2. Я получаю сообщение об ошибке: запрошенный обработчик ... не найден ни в списке основных обработчиков, ни в списке обработчиков прослушивания. - person Diego Augusto Molina; 04.07.2019

Вы сможете это сделать, если включите файл обработчика.

Пример:

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

Но я не думаю, что это элегантно.

Более элегантный способ - создать пьесу, которая управляет обеими ролями, примерно так:

- hosts: all
  roles:
  - role1
  - role2

Это позволит обеим ролям вызывать другие обработчики.

Но я бы снова предложил сделать все это в одной роли и в отдельных файлах и использовать условное включение http://docs.ansible.com/playbooks_conditionals.html#conditional-imports

надеюсь, это поможет

person DomaNitro    schedule 26.03.2014
comment
в 2.6.12 неявно разделяются обработчики. По крайней мере, в моем случае. - person Deil; 23.04.2019
comment
В 2014 году пользователь mpdehaan сказал, что можно определить обработчик дважды без проблем, например перезапустите apache, и система примет последнее определение. Однако мои тесты (Ansible 2.9.4) показывают, что если обработчики в разных ролях определены, они запускаются оба, но если они определены только один раз, даже если в другой роли, они все равно run, так в том, что они глобальные. Нет необходимости импортировать обработчики из другой роли. - person bitinerant; 21.02.2020

Вы можете импортировать дополнительные обработчики из YourRole/handlers/main.yml файла, используя import_tasks.

Итак, если MyRole нужно вызвать обработчики в каком-то OtherRole, roles/MyRole/handlers/main.yml будет выглядеть так:

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

Конечно, roles/MyRole/handlers/main.yml также может включать дополнительные обработчики.

Таким образом, если я хочу запускать MyRole без выполнения задач из OtherRole, ansible сможет правильно импортировать и запускать обработчики из OtherRole

person Dima L.    schedule 25.02.2018

У меня была аналогичная проблема, но мне нужно было выполнить много действий в других зависимых ролях.

Поэтому вместо того, чтобы вызывать обработчика, мы устанавливаем такой факт:

- 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
person stackdump    schedule 15.02.2016
comment
Нет необходимости устанавливать факт, переменная, установленная через register, имеет такой же срок жизни, как и факт. - person Luke Antins; 22.05.2016
comment
Переменные @LukeAntins, установленные через регистр, проходят через все бесполезные вещи, которые модуль считает полезными. Установка переменной , которую вы определяете на известное значение, намного более предсказуема. Он отделяет ваш playbook от конкретных реализаций модулей и от использования конкретных модулей для генерации переменной. - person DylanYoung; 07.02.2019

В настоящее время я использую 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, после чего виртуальная машина будет перезагружена.

P.S. Я не знаю, какая именно версия Ansible поддерживает это.

Изменить: исправление отступа кода

person kxu    schedule 06.04.2021