Продвинутые методы обработки вывода
Теперь, когда мы понимаем основы захвата вывода скриптов, давайте рассмотрим некоторые более продвинутые методы обработки и отображения вывода в плейбуках Ansible.
Обработка ошибок скриптов
При запуске скриптов важно правильно обрабатывать условия ошибок. Ansible помечает задачу как неудачную, если команда возвращает ненулевой код выхода. Давайте создадим плейбук, демонстрирующий обработку ошибок.
Создайте файл с именем error_handling.yml
в вашем каталоге ~/project/ansible-lab
:
---
- name: Handling Script Errors
hosts: localhost
gather_facts: no
tasks:
- name: Run a command that might fail
command: ls /nonexistent_directory
register: cmd_result
ignore_errors: yes
- name: Show error message if command failed
debug:
msg: "Command failed with error: {{ cmd_result.stderr }}"
when: cmd_result.rc != 0
- name: Show success message if command succeeded
debug:
msg: "Command succeeded with output: {{ cmd_result.stdout }}"
when: cmd_result.rc == 0
В этом плейбуке:
- Мы пытаемся перечислить каталог, который не существует
- Мы используем
ignore_errors: yes
, чтобы предотвратить остановку плейбука в случае сбоя команды
- Мы проверяем код возврата (
cmd_result.rc
), чтобы определить, успешно ли выполнена команда или нет
- Мы отображаем соответствующие сообщения в зависимости от результата
Давайте запустим этот плейбук:
cd ~/project/ansible-lab
ansible-playbook -i inventory.ini error_handling.yml
Вы должны увидеть вывод, аналогичный:
PLAY [Handling Script Errors] ***********************************************************
TASK [Run a command that might fail] ***************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["ls", "/nonexistent_directory"], "delta": "0:00:00.003398", "end": "2023-09-15 12:34:56.789012", "msg": "non-zero return code", "rc": 2, "start": "2023-09-15 12:34:56.785614", "stderr": "ls: cannot access '/nonexistent_directory': No such file or directory", "stderr_lines": ["ls: cannot access '/nonexistent_directory': No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoring
TASK [Show error message if command failed] *********************************************
ok: [localhost] => {
"msg": "Command failed with error: ls: cannot access '/nonexistent_directory': No such file or directory"
}
TASK [Show success message if command succeeded] ****************************************
skipping: [localhost]
PLAY RECAP *******************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=1
Обратите внимание, что, несмотря на сбой команды, плейбук продолжает выполняться и отображает сообщение об ошибке.
Форматирование многострочного вывода
Давайте создадим более сложный скрипт, который генерирует многострочный вывод, а затем отформатируем его красиво в нашем плейбуке.
Создайте файл с именем package_info.sh
в вашем каталоге ~/project/ansible-lab
:
#!/bin/bash
echo "TOP 5 LARGEST INSTALLED PACKAGES"
echo "================================"
dpkg-query -W -f='${Installed-Size}\t${Package}\n' | sort -n -r | head -5
Сделайте его исполняемым:
chmod +x ~/project/ansible-lab/package_info.sh
Теперь создайте плейбук для запуска этого скрипта и красивого форматирования вывода. Создайте файл с именем formatted_output.yml
:
---
- name: Format Script Output
hosts: localhost
gather_facts: no
tasks:
- name: Run package info script
shell: ./package_info.sh
register: pkg_info
- name: Display raw output
debug:
msg: "{{ pkg_info.stdout }}"
- name: Display formatted output with a title
debug:
msg: |
Below is the package information:
--------------------------------
{% for line in pkg_info.stdout_lines %}
{{ line }}
{% endfor %}
--------------------------------
Total lines: {{ pkg_info.stdout_lines | length }}
Этот плейбук:
- Запускает наш скрипт
package_info.sh
- Отображает необработанный вывод
- Использует шаблон Jinja2 для форматирования вывода с заголовком и нижним колонтитулом
Давайте запустим его:
ansible-playbook -i inventory.ini formatted_output.yml
Вы должны увидеть красиво отформатированный вывод:
PLAY [Format Script Output] ***********************************************************
TASK [Run package info script] ********************************************************
changed: [localhost]
TASK [Display raw output] *************************************************************
ok: [localhost] => {
"msg": "TOP 5 LARGEST INSTALLED PACKAGES\n================================\n112233\tsome-large-package\n99887\tanother-package\n...\n"
}
TASK [Display formatted output with a title] ******************************************
ok: [localhost] => {
"msg": "Below is the package information:\n--------------------------------\nTOP 5 LARGEST INSTALLED PACKAGES\n================================\n112233\tsome-large-package\n99887\tanother-package\n...\n--------------------------------\nTotal lines: 7"
}
PLAY RECAP ****************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Условное отображение вывода
Иногда вы хотите отображать вывод только при определенных условиях, например, при работе в подробном режиме. Давайте посмотрим, как это сделать.
Создайте файл с именем conditional_output.yml
в вашем каталоге ~/project/ansible-lab
:
---
- name: Conditional Output Display
hosts: localhost
gather_facts: yes
tasks:
- name: Get disk usage information
shell: df -h
register: disk_info
- name: Display disk usage (always shown)
debug:
msg: "{{ disk_info.stdout_lines[0:2] }}"
- name: Display detailed disk usage (only in verbose mode)
debug:
msg: "{{ disk_info.stdout_lines }}"
verbosity: 1
В этом плейбуке:
- Мы захватываем информацию об использовании диска
- Мы всегда отображаем сводку (первые две строки)
- Мы отображаем полные сведения только при работе в подробном режиме (с флагом
-v
)
Давайте сначала запустим его в обычном режиме:
ansible-playbook -i inventory.ini conditional_output.yml
Теперь давайте запустим его в подробном режиме:
ansible-playbook -i inventory.ini conditional_output.yml -v
Вы заметите, что в подробном режиме вы получаете полную информацию об использовании диска, а в обычном режиме вы видите только сводку.
Эта техника полезна для скрытия потенциально конфиденциального или ошеломляющего вывода по умолчанию, при этом делая его доступным при необходимости для отладки.