Как мне написать ANSIBLE обработчик, который может запустить задачу при сбое? - PullRequest
0 голосов
/ 14 мая 2018

Я хочу использовать ansible 2.5.2 для выполнения некоторых задач по обновлению и отката к предыдущей установке, если они не пройдены. Я использую уведомление для всех изменений конфигурации, чтобы предотвратить обновление, если нет никаких изменений. Сначала я думал использовать операторы block: и rescue: в обработчике для этого уведомления.

Однако, поскольку это еще не поддерживается (https://github.com/ansible/ansible/issues/14270) Вместо этого я воспользовался предложенным обходным решением, включив еще одну задачу в блок уведомлений, чтобы получить нечто, эквивалентное следующему:

upgrade
|-handlers
  main.yml
  - name: upgrade task
    include: upgrade.yml
|-tasks
  main.yml
  - name: Update configuration 1
    template: src=conf.j2 dest={{ conf_dir }}/conf.conf
    notify: upgrade task
  - name: Update configuration 2
    template: src=conf2.j2 dest={{ conf_dir }}/conf2.conf
    notify: upgrade task

  upgrade.yml
  - block:
    - debug: msg="Starting upgrade"
    - name: Simulate failure of first of many upgrade tasks
      command: /bin/false
    rescue:
    - debug: msg="Upgrade failed, rolling back now"
    - name: Rollback deploy
      include: rollback.yml
    always:
    - debug: msg="Upgrade complete"

  rollback.yml
    ....

Как и ожидалось, это не сработает:

RUNNING HANDLER [upgrade : Simulate failure of first of many upgrade tasks] 
fatal: [hostname]: FAILED!

но Upgrade failed или Upgrade complete не печатается, а rollback.yml не выполняется.

Возможные варианты:

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

Может кто-нибудь определить проблему или дать мне несколько советов по структурированию этой проблемы поддерживаемым способом? Единственная альтернатива, которую я могу придумать, - это использовать listen, чтобы сгруппировать обработчики, пометить их как измененные, но не сбойные при сбое, и заставить их уведомить о задаче отката, но на первый взгляд кажется, что это будет чрезвычайно хрупко.

1 Ответ

0 голосов
/ 15 мая 2018

Ответом являются оба 2. и 3. Если пример блока перенесен в main.yml, он отлично работает, исключая 1.

В комментариях к запросу на функцию, который я связал в своемвопрос, другой человек упоминает, что у меня была такая же проблема еще в 2016 году, поэтому сейчас я поднял новую ошибку: https://github.com/ansible/ansible/issues/40130

Чтобы ответить на вопрос о лучшей альтернативе очень хакерскому обходному пути для обходного пути, который я предложил,можно использовать register: в качестве условия, чтобы разрешить перемещение блока в tasks/main.yml:

- name: Update configuration 1
  template: src=conf.j2 dest={{ conf_dir }}/conf.conf
  register: update1

- name: Update configuration 2
  template: src=conf2.j2 dest={{ conf_dir }}/conf2.conf
  register: update2

- block:
  - debug: msg="Starting upgrade"
    when: update1.changed or update2.changed

  - name: Simulate failure of first of many upgrade tasks
    command: /bin/false
    when: update1.changed or update2.changed

  rescue:
  - debug: msg="Upgrade failed, rolling back now"

  - name: Rollback deploy
    include: rollback.yml

  always:
  - debug: msg="Upgrade complete"

Это все еще хрупко, так как вам нужно помнить, чтобы обновлять все в блоке каждый раз, когдаЗадача конфигурации добавлена.Если вы в порядке с обработчиками ручной очистки, следующий подход устраняет эту проблему и немного чище ИМХО:

- name: Update configuration 1
  template: src=conf.j2 dest={{ conf_dir }}/conf.conf
  notify: trigger upgrade

- name: Update configuration 2
  template: src=conf2.j2 dest={{ conf_dir }}/conf2.conf
  notify: trigger upgrade

- meta: flush_handlers

- block:
  - debug: msg="Starting upgrade"
    when: upgrade is defined and upgrade.changed
    ...

, где trigger upgrade - это обработчик в handlers/main.yml, который делает фиктивное изменение, то есть:

- name: trigger upgrade
  shell: echo "Upgrading"
  register: upgrade

Я думаю, что это лучшее, что можно сделать, пока ошибка не будет исправлена ​​или блоки не разрешены в обработчиках.

...