Spec-Zone.ru › Ansible 2.9

Обработка ошибок в Playbook

  • Игнорирование неудачных команд
  • Сброс недоступных хостов
  • Обработчики и ошибки
  • Управление определением ошибки
  • Переопределение результата изменения
  • Прерывание выполнения Playbook
  • Использование блоков

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

Иногда команда, возвращающая значение отличное от 0, не является ошибкой. Иногда команде не нужно сообщать, что она «изменила» удаленную систему. Этот раздел описывает, как изменить стандартное поведение Ansible для определённых задач, чтобы поведение вывода и обработки ошибок было желаемым.

Игнорирование неудачных команд

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

- name: this will not be counted as a failure
  command: /bin/false
  ignore_errors: yes

Обратите внимание, что указанная система управляет только значением возврата ошибки конкретной задачи, поэтому, если используется неопределённая переменная или синтаксическая ошибка, всё равно будет выброшено сообщение об ошибке, которое пользователи должны будут обработать. Обратите внимание, что это не предотвратит ошибки при подключении или выполнении.

Этот функционал работает только когда задача может быть выполнена и вернуть значение «failed».

Сброс недоступных хостов

Новая функция в версии 2.2.

Ошибки подключения устанавливают хосты как «НЕДОСТУПНЫЕ», что удалит их из списка активных хостов для выполнения. Чтобы восстановиться от этих проблем, вы можете использовать meta: clear_host_errors для повторной активации всех помеченных в настоящее время хостов, чтобы последующие задачи могли снова их использовать.

Обработчики и ошибки

Когда задача завершается с ошибкой на хосте, обработчики, которые были ранее уведомлены, не будут запущены на этом хосте. Это может привести к ситуациям, когда несвязанная ошибка может оставить хост в неожиданном состоянии. Например, задача может обновить файл конфигурации и уведомить обработчик о перезапуске некоторой службы. Если впоследствии в рамках того же Playbook задача завершится с ошибкой, служба не будет перезапущена, несмотря на изменение конфигурации.

Вы можете изменить это поведение с помощью параметра командной строки --force-handlers, или включив force_handlers: True в Playbook, или force_handlers = True в ansible.cfg. Принудительное выполнение обработчиков приведет к их запуску при уведомлении, даже если задача завершится с ошибкой на данном хосте. (Обратите внимание, что некоторые ошибки все ещё могут помешать обработчику запуститься, например, если хост станет недоступным.)

Управление определением ошибки

Ansible позволяет определять, что означает «ошибка» в каждой задаче, используя условное выражение failed_when. Как и со всеми условными выражениями в Ansible, списки нескольких failed_when условий объединяются с неявным and, что означает, что задача завершается с ошибкой только тогда, когда все условия выполнены. Если вы хотите вызвать ошибку, когда выполнено любое из условий, вам необходимо определить условия в строке с явным оператором or.

Вы можете проверить ошибку, выполнив поиск слова или фразы в выводе команды:

- name: Fail task when the command error output prints FAILED
  command: /usr/bin/example-command -x -y -z
  register: command_result
  failed_when: "'FAILED' in command_result.stderr"

или на основе кода возврата:

- name: Fail task when both files are identical
  raw: diff foo/file1 bar/file2
  register: diff_cmd
  failed_when: diff_cmd.rc == 0 or diff_cmd.rc >= 2

В предыдущих версиях Ansible это можно было сделать следующим образом:

- name: this command prints FAILED when it fails
  command: /usr/bin/example-command -x -y -z
  register: command_result
  ignore_errors: True

- name: fail the play if the previous command did not succeed
  fail:
    msg: "the command failed"
  when: "'FAILED' in command_result.stderr"

Вы также можете объединить несколько условий для проверки ошибки. Эта задача завершится с ошибкой, если оба условия истинны:

- name: Check if a file exists in temp and fail task if it does
  command: ls /tmp/this_should_not_be_here
  register: result
  failed_when:
    - result.rc == 0
    - '"No such" not in result.stdout'

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

failed_when: result.rc == 0 or "No such" not in result.stdout

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

- name: example of many failed_when conditions with OR
  shell: "./myBinary"
  register: ret
  failed_when: >
    ("No such file or directory" in ret.stdout) or
    (ret.stderr != '') or
    (ret.rc == 10)

Переопределение результата изменения

При выполнении оболочки/команды или другого модуля обычно сообщается о статусе «изменено» в зависимости от того, считает ли он, что он повлиял на состояние машины.

Иногда, на основе кода возврата или вывода, вы будете знать, что никаких изменений не было, и захотите переопределить результат «изменено», чтобы он не отображался в отчёте или не вызывал обработчики:

tasks:

  - shell: /usr/bin/billybass --mode="take me to the river"
    register: bass_result
    changed_when: "bass_result.rc != 2"

  # this will never report 'changed' status
  - shell: wall 'beep'
    changed_when: False

Вы также можете объединить несколько условий для переопределения результата «изменено»:

- command: /bin/fake_command
  register: result
  ignore_errors: True
  changed_when:
    - '"ERROR" in result.stderr'
    - result.rc == 2

Прерывание выполнения Playbook

Иногда желательно прервать весь Playbook при ошибке, а не просто пропустить оставшиеся задачи для хоста.

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

- hosts: somehosts
  any_errors_fatal: true
  roles:
    - myrole

- hosts: somehosts
  tasks:
    - block:
        - include_tasks: mytasks.yml
      any_errors_fatal: true

Для более точного управления max_fail_percentage может быть использовано для прерывания выполнения после того, как определённый процент хостов завершится с ошибкой.

Использование блоков

Большинство из того, что можно применить к отдельной задаче (за исключением циклов), может быть применено на уровне блоков, что также значительно облегчает установку данных или директив, общих для задач. Блоки также вводят возможность обработки ошибок аналогично исключениям в большинстве языков программирования. Блоки обрабатывают только статус «failed» задачи. Ошибки в определении задачи или недоступный хост не являются «восстанавливаемыми» ошибками:

tasks:
- name: Handle the error
  block:
    - debug:
        msg: 'I execute normally'
    - name: i force a failure
      command: /bin/false
    - debug:
        msg: 'I never execute, due to the above task failing, :-('
  rescue:
    - debug:
        msg: 'I caught an error, can do stuff here to fix it, :-)'

Это «вернёт» статус ошибки внешней block задачи для выполнения, и Playbook продолжится так, как если бы она завершилась успешно. Дополнительные примеры см. в разделе обработки ошибок в блоках.

См. также

О Playbook
Введение в Playbook
Рекомендации по использованию
Рекомендации по использованию Playbook
Условные операторы
Условные операторы в Playbook
Использование переменных
Всё о переменных
Список рассылки пользователей
У вас есть вопрос? Зайдите на google группу!
irc.freenode.net
#ansible IRC чат канал

© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.9/user_guide/playbooks_error_handling.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API