J'essaie d'inclure un fichier uniquement s'il existe. Cela permet de personnaliser les "tâches/rôles" entre les "tâches/rôles" existants, si nécessaire par l'utilisateur de mon rôle. J'ai trouvé ça:
- include: ...
when: condition
Mais la documentation Ansible précise que:
"Toutes les tâches sont évaluées, mais le conditionnel est appliqué à chaque tâche" - http://docs.ansible.com/playbooks_conditionals.html#applying-when-to-roles-and-includes
Alors
- stat: path=/home/user/optional/file.yml
register: optional_file
- include: /home/user/optional/file.yml
when: optional_file.stat.exists
Echouera si le fichier en cours d’inclusion n’existe pas. J'imagine qu'il pourrait exister un autre mécanisme permettant à un utilisateur d'ajouter des tâches à une recette existante. Je ne peux pas laisser l'utilisateur ajouter un rôle après le mien, car il n'aurait pas le contrôle de la commande: son rôle sera exécuté après le mien.
Merci à tous pour votre aide! Je réponds à ma propre question après avoir finalement essayé toutes les réponses et le code de ma propre question dans Ansible d'aujourd'hui: ansible 2.0.1.0
Mon code original semble fonctionner maintenant, sauf que le fichier facultatif que je cherchais se trouvait sur mon ordinateur local. Je devais donc exécuter stat via local_action et définir become: no
pour cette tâche particulière, afin que personne ne tente pas de réaliser Sudo. dans ma machine locale et erreur avec: "Sudo: un mot de passe est requis\n"
- local_action: stat path=/home/user/optional/file.yml
register: optional_file
become: no
- include: /home/user/optional/file.yml
when: optional_file.stat.exists
Le with_first_found
conditionnel peut accomplir cela sans stat
ou local_action
. Cette conditionnelle parcourra une liste de fichiers locaux et exécutera la tâche avec item
défini sur le chemin du premier fichier existant. Inclure skip: true
sur les options with_first_found
l'empêchera d'échouer si le fichier n'existe pas.
Exemple:
- hosts: localhost
connection: local
gather_facts: false
tasks:
- include: "{{ item }}"
with_first_found:
- files:
- /home/user/optional/file.yml
skip: true
J'utilise quelque chose de similaire mais pour le module de fichier et ce qui m'a été difficile, c'est de vérifier la définition de la variable, essayez par exemple
when: optional_file.stat.exists is defined and optional_file.stat.exists
la tâche ne sera exécutée que lorsque la variable existe.
En utilisant ansible-2.1.0, je peux utiliser des extraits comme ceci dans mon livre de jeu:
- hosts: all
gather_facts: false
tasks:
- name: Determine if local playbook exists
local_action: stat path=local.yml
register: st
- include: local.yml
when: st.stat.exists
Je n'obtiens aucune erreur/échec lorsque local.yml
n'existe pas et que le playbook est exécuté (en tant que playbook, ce qui signifie qu'il commence par la ligne hosts:
, etc.)
Vous pouvez faire la même chose au niveau de la tâche à la place avec un code similaire . Utiliser stat
semble fonctionner correctement.
Je pourrais passer du temps ici à critiquer les dispositions de gestion des erreurs d’Anse, mais en bref, vous avez raison et vous ne pouvez pas utiliser le module stat
à cette fin pour des raisons données.
La solution la plus simple pour la plupart des problèmes rencontrés est de le faire en dehors de celui-ci. Par exemple.
- Shell: test -f /home/user/optional/file.yml # or use -r if you're too particular.
register: optional_file
failed_when: False
- include: /home/user/optional/file.yml
when: optional_file.rc == 0
- debug: msg="/home/user/optional/file.yml did not exist and was not included"
when: optional_file.rc != 0
* failed_when
ajouté pour éviter que l'hôte ne soit exclu de tâches ultérieures lorsque le fichier n'existe pas.
Il existe également la possibilité d'utiliser un filtre Jinja2 pour cela:
- set_fact: optional_file="/home/user/optional/file.yml"
- include: ....
when: optional_file|exists
La meilleure option que j'ai proposée jusqu'à présent est la suivante:
- include: "{{ hook_variable | default(lookup('pipe', 'pwd') ~ '/hooks/empty.yml') }}"
Ce n'est pas exactement un "si-existe", mais cela donne le même résultat aux utilisateurs de votre rôle. Créez quelques variables dans votre rôle et un fichier vide par défaut. Les filtres Jinja "default" et "lookup" se chargent de revenir sur le fichier vide au cas où la variable ne serait pas définie.
Pour plus de commodité, un utilisateur peut utiliser la variable {{ playbook_dir }}
pour définir les chemins:
hook_variable: "{{ playbook_dir }}/hooks/tasks-file.yml"
Si je ne me trompe pas, vous voulez continuer le livret même si la déclaration est fausse?
Si oui, veuillez ajouter cette ligne après when:
ignore_errors: True
Donc, vos tâches ressembleront à ceci:
- stat: path=/home/user/optional/file.yml
register: optional_file
- include: /home/user/optional/file.yml
when: optional_file.stat.exists
ignore_errors: True
Faites-le moi savoir, si je comprends bien votre question, ou peut aider davantage. Merci