web-dev-qa-db-fra.com

Comment puis-je afficher les progrès pour une tâche Ansible de longue durée?

J'ai quelques tâches Ansible qui effectuent malheureusement des opérations longues, comme l'exécution d'une opération de synchronisation avec un dossier S3. Il n'est pas toujours évident de savoir s'ils progressent ou s'ils sont bloqués (ou si la connexion SSH est morte), il serait donc agréable d'afficher une sorte de résultat de progression. Si stdout/stderr de la commande était directement affiché, je le verrais bien, mais Ansible capturerait la sortie.

Retour de la tuyauterie problème difficile à résoudre par Ansible dans sa forme actuelle . Mais y a-t-il des astuces Ansible que je peux utiliser pour donner une sorte d'indication que les choses bougent encore?

Le billet actuel est https://github.com/ansible/ansible/issues/487

33
Xiong Chiamiov

Ansible a depuis mis en œuvre ce qui suit:

---
# 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

Pour plus d'informations, voir documentation officielle sur le sujet (assurez-vous de choisir votre version d'Ansible).

4
pydoge

Je suis tombé sur ce problème aujourd'hui sur OSX, où j'exécutais une commande docker Shell qui a pris beaucoup de temps à compiler et où il n’existait aucune sortie. C'était très frustrant de ne pas comprendre si le commandement avait été suspendu ou s'il progressait lentement.

J'ai décidé de diriger la sortie (et l'erreur) de la commande Shell vers un port, qui pourrait ensuite être écouté via Netcat dans un terminal séparé.

myplaybook.yml

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

Et dans une fenêtre de terminal séparée:

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

Notez que je dirige la sortie d'erreur vers le même port; Je pourrais aussi facilement diriger vers un autre port.

En outre, j'ai fini par définir une variable appelée nc_port qui permet de changer le port si ce port est utilisé. La tâche ansible ressemble alors à:

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

Notez que la commande myLongRunningApp est en cours d’exécution sur localhost (c’est-à-dire que l’hôte est défini dans l’inventaire) et c’est pourquoi j’écoute localhost avec nc.

19
John

Vous pouvez faire plusieurs choses, mais comme vous l'avez justement souligné, Ansible dans sa forme actuelle n'offre pas vraiment une bonne solution.

Solutions officielles:

Une idée est de marquer la tâche comme asynchrone et de l'interroger. Évidemment, cela ne convient que s’il est capable de fonctionner de cette manière sans provoquer d’échec ailleurs dans votre Playbook. Les documents asynchrones sont here et voici un exemple qui en découle:

- 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

Cela peut au moins vous donner un "ping" pour savoir que la tâche n'est pas en suspens.

La seule autre méthode officiellement approuvée serait la tour Ansible, qui comporte des barres de progression pour les tâches mais n'est pas gratuite.

Solutions hackées:

Au-delà de ce qui précède, vous allez devoir rouler le vôtre. Votre exemple spécifique de synchronisation d'un compartiment S3 pourrait être surveillé assez facilement avec un script appelant périodiquement l'AWS CLI et comptant le nombre d'éléments dans un compartiment, mais ce n'est pas une bonne solution générique.

La seule chose que je puisse imaginer être assez efficace serait de regarder la session SSH entrante depuis l’un de vos nœuds.

Pour ce faire, vous pouvez configurer l'utilisateur Ansible sur cette machine pour qu'il se connecte via un écran et le surveille activement. Alternativement peut-être en utilisant le log_output dans l’entrée sudoers de cet utilisateur, ce qui vous permet de personnaliser le fichier. Les détails de log_output sont disponibles sur le page de manuel sudoers

10
Tom Manterfield

Si vous êtes sur Linux, vous pouvez utiliser systemd-run pour créer une unité transitoire et inspecter la sortie avec journalctl, comme:

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

Et dans une autre session

Sudo journalctl -xf --unit foo

Cela donnerait quelque chose comme:

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
3
geckos