ansible: передать переменную обработчику

Я использую «глаз» в качестве супервизора, и при изменении шаблонов приходится запускать что-то вроде этого:

eye load service.rb
eye restart service.rb

Я хочу определить это как единый обработчик для всех приложений и назвать его как

eye reload appname

И в обработчике работают так:

- name: reload eye service
command: eye load /path/{{ service }}.rb && eye restart {{ service }}

Но я не могу найти способ передать переменную обработчику. Является ли это возможным?


person hryamzik    schedule 20.10.2014    source источник
comment
Это выглядит как дубликат stackoverflow .com/questions/25694249/   -  person Rachel    schedule 02.11.2014
comment
использовать модуль оболочки [docs.ansible.com/ansible/shell_module.html]   -  person Valeriy Solovyov    schedule 09.03.2016
comment
@ valeriy-solovyov, это не имеет никакого значения, за исключением того, что && будет работать, как и ожидалось. Параметризованные обработчики работают только в ansible 2.0, поэтому правильным способом является использование имени службы в имени обработчика: - name: reload eye {{ service }} shell: eye load /path/{{ service }}.rb && eye restart {{ service }}   -  person hryamzik    schedule 10.03.2016
comment
Это поддерживается начиная с версии 2.1.1.0. Убедитесь, что вы используете кавычки вокруг любой строки с переменной интерполяцией.   -  person simonwo    schedule 23.11.2016
comment
@hryamzik ​​Это тот глаз, о котором вы говорите? github.com/kostya/eye   -  person blong    schedule 29.06.2020
comment
да github.com/gitinsky/ansible-role-eye   -  person hryamzik    schedule 30.06.2020


Ответы (3)


Не делай этого. Я понимаю ваше желание использовать Ansible в качестве инструмента программирования, где «обработчик» — это «функция», которую вы «вызываете», но это не так.

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

Ключевая проблема заключается в том, что ansible не поддерживает «передачу аргументов» чему-либо (кроме модулей). Все трюки, о которых вы читали или придумывали сами, изменят глобальную переменную. Если вы хоть немного писали на каком-либо языке, то знаете, что эта программа, в которой каждая функция использует глобальные переменные (для чтения и записи, а также для передачи аргументов), в корне ошибочна.

Итак, как это сделать в очень хорошем и читабельном Ansible?

Да просто написал отдельный обработчик для каждого сервиса. Это самый чистый и простой Ansible. Легко читается, легко меняется.

Кстати: если вам нужно выполнить действия в цепочке, не объединяйте их с помощью '&&'.

Используйте два отдельных обработчика:

- foo:
  notify:
    - eye reload
    - eye restart foo

(обратите внимание, что порядок обработчиков определяется в списке обработчиков, а не в списке «уведомления»).

Кстати, если у вас мало сервисов, вы сэкономите на нескольких операциях перезагрузки - «перезагрузка глаза» будет вызываться один раз.

person George Shuklin    schedule 26.10.2020

обработчики/main.yml:

- name: restart my service
  shell: eye load /path/{{ service }}.rb && eye restart {{ service }}

Таким образом, вы можете настроить переменную через defaults/main.yml:

service : "service"

или вы можете определить {{ service }} через командную строку:

ansible-playbook -i xxx path/to/playbook -e "service=service"

http://docs.ansible.com/ansible/playbooks_variables.html

PS: http://docs.ansible.com/ansible/playbooks_intro.html#playbook-language-

example
---
- hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
  - name: ensure apache is at the latest version
    yum: name=httpd state=latest
  - name: write the apache config file
    template: src=/srv/httpd.j2 dest=/etc/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running (and enable it at boot)
    service: name=httpd state=started enabled=yes
  handlers:
    - name: restart apache
      service: name=httpd state=restarted

http://docs.ansible.com/ansible/playbooks_intro.html#handlers-running-operations-on-change

Если вы когда-нибудь захотите сразу сбросить все команды обработчика, в 1.2 и более поздних версиях вы можете:

tasks:
   - shell: some tasks go here
   - meta: flush_handlers
   - shell: some other tasks
person Valeriy Solovyov    schedule 10.03.2016
comment
Это сработает, но только для одного приложения, которое необходимо перезапустить. Обработчик будет запущен только один раз в конце playbook. Однако это сработает, если обработчик перебирает список и для каждой службы, которую необходимо перезапустить, элемент добавляется в этот список через set_fact. - person udondan; 10.03.2016
comment
Я добавил пример, когда вы очищаете обработчики перед следующей задачей. PS: Может быть, вам нужно реорганизовать свой playbook? - person Valeriy Solovyov; 10.03.2016

Вы не можете этого сделать, но вы можете использовать set_fact, чтобы установить факты, к которым может получить доступ обработчик.

person sorin    schedule 15.04.2021