Захват различных типов вывода
На предыдущем шаге мы захватили и отобразили стандартный вывод нашего скрипта. Однако при выполнении скриптов существует несколько типов вывода, которые мы можем захотеть захватить:
- Стандартный вывод (stdout): Обычный вывод скрипта
- Стандартный вывод ошибок (stderr): Сообщения об ошибках и предупреждения
- Код возврата (rc): Статус завершения скрипта (0 обычно означает успех, ненулевые значения указывают на ошибки)
Давайте создадим новый плейбук, который захватывает и отображает все три типа вывода.
Создайте новый файл с именем capture_all_output.yml в каталоге ~/project/ansible-output-demo:
- Нажмите на меню "File"
- Выберите "New File"
- Сохраните его как
capture_all_output.yml в каталоге ~/project/ansible-output-demo
Добавьте следующее содержимое в файл capture_all_output.yml:
---
- name: Capture All Types of Script Output
hosts: local
gather_facts: no
tasks:
- name: Execute the info.sh script
command: "{{ playbook_dir }}/scripts/info.sh"
register: script_output
- name: Display standard output
debug:
msg: "Standard Output (stdout):"
- name: Display stdout content
debug:
var: script_output.stdout_lines
- name: Display standard error
debug:
msg: "Standard Error (stderr):"
- name: Display stderr content
debug:
var: script_output.stderr_lines
- name: Display return code
debug:
msg: "Return Code: {{ script_output.rc }}"
Этот плейбук выполняет наш скрипт, а затем отображает:
- Стандартный вывод с использованием
script_output.stdout_lines
- Стандартный вывод ошибок с использованием
script_output.stderr_lines
- Код возврата с использованием
script_output.rc
Запуск улучшенного плейбука
Давайте запустим наш новый плейбук:
cd ~/project/ansible-output-demo
ansible-playbook -i inventory capture_all_output.yml
Вы должны увидеть все три типа вывода:
PLAY [Capture All Types of Script Output] *****************************
TASK [Execute the info.sh script] *************************************
changed: [localhost]
TASK [Display standard output] ****************************************
ok: [localhost] => {
"msg": "Standard Output (stdout):"
}
TASK [Display stdout content] *****************************************
ok: [localhost] => {
"script_output.stdout_lines": [
"=== System Information ===",
"Hostname: ubuntu",
"Date: Tue Oct 17 12:40:22 UTC 2023",
"Kernel: 5.15.0-1031-aws",
"Memory:",
" total used free shared buff/cache available",
"Mem: 7.7Gi 1.2Gi 5.2Gi 12Mi 1.3Gi 6.3Gi",
"Swap: 0B 0B 0B",
"=== Standard Output ===",
"This is standard output",
"Hello from the script!"
]
}
TASK [Display standard error] *****************************************
ok: [localhost] => {
"msg": "Standard Error (stderr):"
}
TASK [Display stderr content] *****************************************
ok: [localhost] => {
"script_output.stderr_lines": [
"=== Standard Error ===",
"This is standard error",
"An example error message"
]
}
TASK [Display return code] ********************************************
ok: [localhost] => {
"msg": "Return Code: 0"
}
PLAY RECAP **********************************************************
localhost : ok=6 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Теперь мы можем видеть все типы вывода из нашего скрипта:
- Стандартный вывод показывает информацию о системе и наши обычные сообщения
- Стандартный вывод ошибок показывает наши сообщения об ошибках
- Код возврата равен 0, что указывает на успешное выполнение
Создание скрипта с ошибками
Давайте создадим скрипт, который будет выдавать ошибку и возвращать ненулевой код выхода, чтобы увидеть, как Ansible обрабатывает это.
Создайте новый файл с именем error.sh в каталоге scripts:
- Нажмите на меню "File"
- Выберите "New File"
- Сохраните его как
scripts/error.sh в каталоге ~/project/ansible-output-demo
Добавьте следующее содержимое в файл error.sh:
#!/bin/bash
## Print some standard output
echo "Starting error demonstration script"
echo "This will appear in stdout"
## Print some standard error
echo "This will appear in stderr" >&2
echo "Error: Something went wrong!" >&2
## Exit with a non-zero code to indicate error
exit 1
Сделайте скрипт исполняемым:
chmod +x ~/project/ansible-output-demo/scripts/error.sh
Теперь давайте создадим плейбук для выполнения этого скрипта и обработки ошибки. Создайте новый файл с именем handle_errors.yml:
- Нажмите на меню "File"
- Выберите "New File"
- Сохраните его как
handle_errors.yml в каталоге ~/project/ansible-output-demo
Добавьте следующее содержимое в файл handle_errors.yml:
---
- name: Handle Script Errors
hosts: local
gather_facts: no
tasks:
- name: Execute the error script
command: "{{ playbook_dir }}/scripts/error.sh"
register: script_output
ignore_errors: yes
- name: Display standard output
debug:
var: script_output.stdout_lines
- name: Display standard error
debug:
var: script_output.stderr_lines
- name: Display return code
debug:
msg: "Return Code: {{ script_output.rc }}"
- name: Check if script failed
debug:
msg: "The script failed with return code {{ script_output.rc }}"
when: script_output.rc != 0
Обратите внимание на добавление ignore_errors: yes, которое указывает Ansible продолжать выполнение плейбука, даже если команда завершится неудачно (вернет ненулевой код выхода).
Давайте запустим этот плейбук:
ansible-playbook -i inventory handle_errors.yml
Вы должны увидеть вывод, похожий на следующий:
PLAY [Handle Script Errors] *******************************************
TASK [Execute the error script] ***************************************
changed: [localhost]
TASK [Display standard output] ****************************************
ok: [localhost] => {
"script_output.stdout_lines": [
"Starting error demonstration script",
"This will appear in stdout"
]
}
TASK [Display standard error] *****************************************
ok: [localhost] => {
"script_output.stderr_lines": [
"This will appear in stderr",
"Error: Something went wrong!"
]
}
TASK [Display return code] ********************************************
ok: [localhost] => {
"msg": "Return Code: 1"
}
TASK [Check if script failed] *****************************************
ok: [localhost] => {
"msg": "The script failed with return code 1"
}
PLAY RECAP **********************************************************
localhost : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Этот пример демонстрирует, как:
- Захватывать вывод из скрипта, который выдает ошибку
- Продолжать выполнение плейбука, несмотря на ошибку
- Условно выполнять задачи на основе кода возврата скрипта
На следующем шаге мы рассмотрим более продвинутые варианты использования и лучшие практики работы с выводом скриптов в Ansible.