Подтвердить что ты не робот

Как я могу показать прогресс для долговременной задачи Ansible?

У меня есть некоторые Ansible задачи, которые выполняют, к сожалению, длительные операции - например, выполнение операции синхронизации с папкой S3. Это не всегда ясно, если они прогрессируют или просто застревают (или сбой ssh), так что было бы неплохо отобразить какой-то прогресс. Если команда stdout/stderr была непосредственно отображена, я бы это увидел, но Ansible захватил вывод.

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

Текущий билет https://github.com/ansible/ansible/issues/4870

4b9b3361

Ответ 1

Сегодня я столкнулся с этой проблемой на OSX, где я запускал команду оболочки докеров, которая занимала много времени, и не было никакого выхода во время ее создания. Было очень неприятно не понимать, была ли команда висела или просто прогрессировала медленно.

Я решил передать вывод (и ошибку) команды оболочки на порт, который затем можно было бы прослушать через netcat в отдельном терминале.

myplaybook.yml

- name: run some long-running task and pipe to a port
  shell: myLongRunningApp > /dev/tcp/localhost/4000 2>&1

И в отдельном окне терминала:

$ nc -lk 4000
Output from my
long
running
app will appear here

Обратите внимание, что я передаю вывод ошибки в тот же порт; Я мог бы легко подключиться к другому порту.

Кроме того, я установил переменную с именем nc_port, которая позволит изменить порт в случае использования порта. Последовательная задача выглядит следующим образом:

  shell: myLongRunningApp > /dev/tcp/localhost/{{nc_port}} 2>&1

Обратите внимание, что команда myLongRunningApp выполняется на локальном хосте (т.е. что узел установлен в инвентаре), поэтому я слушаю localhost с помощью nc.

Ответ 2

Есть несколько вещей, которые вы можете сделать, но, как вы правильно указали, Ansible в своей нынешней форме действительно не предлагает хорошего решения.

Официальные решения:

Одна идея - отметить задачу как асинхронную и опросить ее. Очевидно, что это подходит только в том случае, если он способен работать таким образом, не вызывая сбоев в другом месте в вашем плейбуке. Асинхронные документы здесь, и вот пример, снятый с них:

- hosts: all
  remote_user: root
  tasks:
  - name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
    command: /bin/sleep 15
    async: 45
    poll: 5

Это может по крайней мере дать вам "ping", чтобы знать, что задача не висит.

Единственным другим официально одобренным методом будет Ansible Tower, у которого есть индикаторы выполнения задач, но не являются бесплатными.

Хакки-иш-решения:

Помимо вышеизложенного, вам в значительной степени придется сворачивать самостоятельно. Ваш конкретный пример синхронизации ведра S3 можно довольно легко контролировать с помощью script, периодически вызывающего CLI AWS и подсчета количества элементов в ведре, но это вряд ли хорошее, общее решение.

Единственное, что я мог представить, будучи несколько эффективным, - это наблюдать за входящей сессией ssh ​​с одного из ваших узлов.

Для этого вы можете настроить доступного пользователя на этом компьютере для подключения через экран и активно наблюдать за ним. Альтернативно, возможно, используя параметр log_output в записи sudoers для этого пользователя, что позволяет вам зачеркнуть файл. Подробные сведения о log_output можно найти на странице sudoers man

Ответ 3

Если вы работаете в Linux, вы можете использовать systemd-run для создания временного модуля и проверки вывода с помощью journalctl, например:

sudo systemd-run --unit foo \                                      
     bash -c 'for i in {0..10}; do 
                   echo "$((i * 10))%"; sleep 1;
              done;
              echo "Complete"'

И в другой сессии

sudo journalctl -xf --unit foo

Это вывело бы что-то вроде:

Apr 07 02:10:34 localhost.localdomain systemd[1]: Started /bin/bash -c for i in {0..10}; do echo "$((i * 10))%"; sleep 1; done; echo "Complete".
-- Subject: Unit foo.service has finished start-up
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit foo.service has finished starting up.
-- 
-- The start-up result is done.
Apr 07 02:10:34 localhost.localdomain bash[10083]: 0%
Apr 07 02:10:35 localhost.localdomain bash[10083]: 10%
Apr 07 02:10:36 localhost.localdomain bash[10083]: 20%
Apr 07 02:10:37 localhost.localdomain bash[10083]: 30%
Apr 07 02:10:38 localhost.localdomain bash[10083]: 40%
Apr 07 02:10:39 localhost.localdomain bash[10083]: 50%
Apr 07 02:10:40 localhost.localdomain bash[10083]: 60%
Apr 07 02:10:41 localhost.localdomain bash[10083]: 70%
Apr 07 02:10:42 localhost.localdomain bash[10083]: 80%
Apr 07 02:10:43 localhost.localdomain bash[10083]: 90%
Apr 07 02:10:44 localhost.localdomain bash[10083]: 100%
Apr 07 02:10:45 localhost.localdomain bash[10083]: Complete

Ответ 4

С тех пор Ansible реализовал следующее:

---
# Requires ansible 1.8+
- name: 'YUM - async task'
  yum:
    name: docker-io
    state: installed
  async: 1000
  poll: 0
  register: yum_sleeper

- name: 'YUM - check on async task'
  async_status:
    jid: "{{ yum_sleeper.ansible_job_id }}"
  register: job_result
  until: job_result.finished
  retries: 30