Quel est l'équivalent de Puppet à moins que dans Ansible?

9

Contexte: dans Puppet, il est possible d'exécuter une commande à moins qu'elle n'ait déjà été exécutée:

exec { '/bin/echo root >> /usr/lib/cron/cron.allow':
  path   => '/usr/bin:/usr/sbin:/bin',
  unless => 'grep root /usr/lib/cron/cron.allow 2>/dev/null',
}

Objectif: exécuter une commande à moins qu'elle n'ait déjà été exécutée dans Ansible

Les méthodes

tâches / main.yml

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu

Résultats

TASK [ansible-rabbitmq : add vhost sensu] **************************************
fatal: [111.222.333.444]: FAILED! => {"changed": true, "cmd": ["rabbitmqctl",
"add_vhost", "/sensu"], "delta": "0:00:00.210140", "end": 
"2016-07-29 12:55:19.384455", "failed": true, "rc": 2, "start":
"2016-07-29 12:55:19.174315", "stderr": "Error: vhost_already_exists: /sensu", 
"stdout": "Creating vhost \"/sensu\" ...", "stdout_lines": 
["Creating vhost \"/sensu\" ..."], "warnings": []}

Discussion

Google a unless ansiblemontré ce documentwhen . Sur la base de cette documentation, une whendéclaration a été ajoutée:

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu
  when: rabbitmqctl list_vhosts | grep sensu

l'exécution du code a entraîné:

fatal: [192.168.0.9]: FAILED! => {"failed": true, "msg": "The conditional
 check 'rabbitmqctl list_vhosts | grep sensu' failed. The error was: template
 error while templating string: expected token 'end of statement block', got
 'list_vhosts'. String: {% if rabbitmqctl list_vhosts | grep sensu %} True {%
 else %} False {% endif %}\n\nThe error appears to have been in '/etc/ansible
/roles/ansible-rabbitmq/tasks/main.yml': line 10, column 3, but may\nbe
 elsewhere in the file depending on the exact syntax problem.\n\nThe
 offending line appears to be:\n\n\n- name: add vhost sensu\n  ^ here\n"}
  1. Tout d'abord, imaginez que cela whena réussi, puis la commande ne s'exécutera pas, puis elle ressemble plus onlyifà Puppet .
  2. Deuxièmement, si le moment est couronné de succès, faut-il utiliser une marque d'escalade pour simuler un à moins?
  3. Utilisation deregister . Que faire si ce fichier est perdu ou si le vhost a été supprimé par exemple par un humain? Puppet unlessexécute toujours les commandes de sorte qu'il soit clair si la commande doit être exécutée.
030
la source

Réponses:

9

Je pense que ce que vous cherchez est le suivant:

- name: get vhosts
  command: rabbitmqctl list_vhosts
  register: vhosts
  changed_when: false

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu
  when: "'/sensu' not in vhosts.stdout"

Re: # 3 registerne crée pas de fichier. Si vous capturez la sortie de rabbitmqctl list_vhostsvia register, le contenu sera aussi valide que l'état actuel du système.

jscott
la source
3

Le problème est la ligne when: rabbitmqctl list_vhosts | grep sensu. Il n'est pas possible d'utiliser bash ici.

Vous devez placer le rabbitmqctl list_vhosts | grep sensudans une tâche distincte et enregistrer le résultat pour l'utiliser dans la clause when. Vous pouvez utiliser un notfiltre pour obtenir unlessun comportement similaire.

Quelque chose comme ça devrait fonctionner:

- name: Get rabbitmq vhosts.
  command: rabbitmqctl list_vhosts | grep sensu
  register: rabbitmq_vhosts

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu
  when: not 'sensu' in rabbitmq_vhosts.stdout

Dans Get rabbitmq vhosts.cet exemple, le sera toujours exécuté. Le add vhost sensuseul si la chaîne sensu n'est pas dans le registre rabbitmq_vhosts.

Consultez la documentation sur les filtres conditionnels et jinja pour plus d'informations.

Henrik Pingel
la source
Le problème persiste:fatal: [IP]: FAILED! => {"changed": true, "cmd": ["rabbitmqctl", "add_vhost", "/sensu"], "delta": "0:00:00.198681", "end": "2016-07-29 13:43:00.870193", "failed": true, "rc": 2, "start": "2016-07-29 13:43:00.671512", "stderr": "Error: vhost_already_exists: /sensu", "stdout": "Creating vhost \"/sensu\" ...", "stdout_lines": ["Creating vhost \"/sensu\" ..."], "warnings": []}
030
hm, probablement ma faute. Je suppose que c'était une .stdoutmodification manquante de ma réponse.
Henrik Pingel
0

L' whenoption est la seule chose qu'Ansible a concernant les conditions. Mais vous ne pouvez pas y définir directement une commande. whenattend une expression Jinja et est en outre évalué sur l'hôte de contrôle Ansible. Vous devez donc d'abord exécuter une tâche pour récupérer le résultat et l'enregistrer.

- shell: rabbitmqctl list_vhosts | grep sensu
  register: sensu_vhosts

- name: add vhost sensu
  command: rabbitmqctl add_vhost /sensu
  when: sensu_vhosts.stdout_lines < 1

stdout_linesest un tableau de toutes les lignes renvoyées par la tâche shell. Vous pouvez donc compter le nombre d'entrées et exécuter votre tâche uniquement lorsque 0 élément a été retourné

udondan
la source
2
si le / sensu vhost n'existe pas, il en résulte:fatal: [IP]: FAILED! => {"changed": true, "cmd": "rabbitmqctl list_vhosts | grep sensu", "delta": "0:00:00.198769", "end": "2016-07-29 13:45:59.069981", "failed": true, "rc": 1, "start": "2016-07-29 13:45:58.871212", "stderr": "", "stdout": "", "stdout_lines": [], "warnings": []}
030