Je souhaite quitter sans erreur (je connais les modules assert et fail ) lorsque je remplis certaines conditions. Le code suivant se termine mais avec un échec:
tasks:
- name: Check if there is something to upgrade
Shell: if apt-get --dry-run upgrade | grep -q "0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded"; then echo "no"; else echo "yes"; fi
register: upgrading
- name: Exit if nothing to upgrade
fail: msg="Nothing to upgrade"
when: upgrading.stdout == "no"
Dans Ansible 2.2, vous pouvez utiliser end_play
avec le module meta :
- meta: end_play
Vous pouvez également spécifier when
pour mettre fin au jeu de manière conditionnelle:
- meta: end_play
when: upgrading.stdout == "no"
Notez cependant que la tâche ne figure pas dans la sortie de ansible-playbook, que la lecture se termine ou non. En outre, la tâche n'est pas comptée dans le récapitulatif. Donc, vous pourriez faire quelque chose comme:
- block:
- name: "end play if nothing to upgrade"
debug:
msg: "nothing to upgrade, ending play"
- meta: end_play
when: upgrading.stdout == "no"
qui annoncera la fin du jeu juste avant de le terminer, uniquement lorsque la condition est remplie. Si la condition n'est pas remplie, la tâche nommée end play if nothing to upgrade
est correctement ignorée, ce qui fournirait plus d'informations à l'utilisateur sur la raison pour laquelle la lecture se termine ou non.
Bien entendu, cela ne fera que mettre fin à la lecture en cours et pas à tous lectures restantes dans le livre de lecture.
Utilisons ce que Tymoteusz a suggéré pour les rôles:
Divisez votre jeu en deux rôles où le premier rôle exécutera le contrôle (et définira le résultat du contrôle de détention variable) et le second agira en fonction du résultat du contrôle.
J'ai créé aaa.yaml
avec ce contenu:
---
- hosts: all
remote_user: root
roles:
- check
- { role: doit, when: "check.stdout == '0'" }
...
puis rôle check
dans roles/check/tasks/main.yaml
:
---
- name: "Check if we should continue"
Shell:
echo $(( $RANDOM % 2 ))
register: check
- debug:
var: check.stdout
...
puis rôle doit
dans roles/doit/tasks/main.yaml
:
---
- name: "Do it only on systems where check returned 0"
command:
date
...
Et ce fut la sortie:
TASK [check : Check if we should continue] *************************************
Thursday 06 October 2016 21:49:49 +0200 (0:00:09.800) 0:00:09.832 ******
changed: [capsule.example.com]
changed: [monitoring.example.com]
changed: [satellite.example.com]
changed: [docker.example.com]
TASK [check : debug] ***********************************************************
Thursday 06 October 2016 21:49:55 +0200 (0:00:05.171) 0:00:15.004 ******
ok: [monitoring.example.com] => {
"check.stdout": "0"
}
ok: [satellite.example.com] => {
"check.stdout": "1"
}
ok: [capsule.example.com] => {
"check.stdout": "0"
}
ok: [docker.example.com] => {
"check.stdout": "0"
}
TASK [doit : Do it only on systems where check returned 0] *********************
Thursday 06 October 2016 21:49:55 +0200 (0:00:00.072) 0:00:15.076 ******
skipping: [satellite.example.com]
changed: [capsule.example.com]
changed: [docker.example.com]
changed: [monitoring.example.com]
Ce n'est pas parfait: vous verrez sans cesse l'état skipping pour toutes les tâches des systèmes ignorés, mais cela pourrait faire l'affaire.
Ce qui suit m'a été utile, car meta: end_play
semble arrêter l'exécution pour tous les hôtes, pas seulement pour celui qui correspond.
D'abord établir un fait:
- name: Determine current version
become: yes
Slurp:
src: /opt/app/CHECKSUM
register: version_check
ignore_errors: yes
- set_fact:
is_update_needed: "{{ ( version_check['checksum'] | b64decode != installer_file.stat.checksum) }}"
Incluez maintenant cette partie qui ne devrait être exécutée qu'à cette condition:
# update-app.yml can be placed in the same role folder
- import_tasks: update-app.yml
when: is_update_needed
Une solution meilleure et plus logique consiste à inverser la procédure et à ne pas échouer s'il n'y a rien à mettre à niveau (une étape distincte ne faisant que cela), vous pouvez ajouter toutes vos tâches de mise à niveau avec une condition dépendante de la upgrade
. variable. En substance, il suffit d'ajouter
when: upgrading.changed
tâches qui ne doivent être exécutées que lors d’une mise à niveau.
C’est un peu plus de travail, mais cela apporte aussi de la clarté et contient la logique qui affecte une tâche donnée en elle-même, plutôt que de dépendre de quelque chose au-dessus de laquelle peut ou non terminer la tâche plus tôt.