Comment puis-je obliger Ansible à exécuter un script Shell si aucun paquet (rpm) n'est installé? Est-il possible d'utiliser le module yum?
Je ne pense pas que le module yum aiderait dans ce cas. Il a actuellement 3 états: absent, présent et dernier. Comme il semble que vous ne souhaitiez pas réellement installer ou supprimer le paquet (du moins à ce stade), vous devrez le faire en deux étapes manuelles. La première tâche vérifierait si le package existe, puis la seconde appelera une commande en fonction du résultat de la première commande.
Si vous utilisez "rpm -q" pour vérifier si un paquet existe, la sortie ressemblerait à ceci pour un paquet existant:
# rpm -q httpd
httpd-2.2.15-15.el6.centos.1.x86_64
et comme ça si le paquet n'existe pas:
# rpm -q httpdfoo
package httpdfoo is not installed
Ainsi, vos tâches ansibles ressembleraient à ceci:
- name: Check if foo.rpm is installed
command: rpm -q foo.rpm
register: rpm_check
- name: Execute script if foo.rpm is not installed
command: somescript
when: rpm_check.stdout.find('is not installed') != -1
La commande rpm se terminera également avec un 0 si le package existe ou un 1 si le package n'est pas trouvé. Une autre possibilité consiste à utiliser:
when: rpm_check.rc == 1
Basé sur la réponse de Bruce P ci-dessus, une approche similaire pour les fichiers apt/deb est
- name: Check if foo is installed
command: dpkg-query -l foo
register: deb_check
- name: Execute script if foo is not installed
command: somescript
when: deb_check.stdout.find('no packages found') != -1
Relatif à cela.
En réunissant le tout, Playbook complet pour Debian
(Ubuntu) qui met à jour le paquet uniquement s'il est déjà installé:
---
- name: Update package only if already installed (Debian)
hosts: all
Sudo: yes
tasks:
- name: Check if Package is installed
Shell: dpkg-query -W -f='${Status}' {{ package }} | grep 'install ok installed'
register: is_installed
failed_when: no
changed_when: no
- name: Update Package only if installed
apt:
name: {{ package }}
state: latest
update_cache: yes
when: is_installed.rc == 0
Malheureusement, Ansible ne prend toujours pas en charge la mise à jour simple des paquets, voir ex: https://github.com/ansible/ansible/issues/10856
Si le paquet peut être installé via le gestionnaire de paquets système (yum, apt, etc.) lui-même, vous pouvez utiliser l'indicateur de mode de vérification d'ansible pour enregistrer le statut d'installation sans installer réellement le paquet.
- name: check if package is installed
package:
name: mypackage
state: present
check_mode: true
register: mypackage_check
- name: run script if package installed
Shell: myscript.sh
when: not mypackage_check.changed
Depuis Ansible 2.5, vous pouvez utiliser le module package_facts :
- name: Gather package facts
package_facts:
manager: auto
- name: Debug if package is present
debug:
msg: 'yes, mypackage is present'
when: '"mypackage" in ansible_facts.packages'
- name: Debug if package is absent
debug:
msg: 'no, mypackage is absent'
when: '"mypackage" not in ansible_facts.packages'
Remarque: vous avez besoin des liaisons python pour apt/rpm installées sur la cible, par exemple python-apt
pour Debian.
Vous ne devriez pas utiliser dpkg -l package
parce qu'il n'a aucune idée si votre paquet a été supprimé ou est toujours installé.
Il vaut probablement mieux utiliser dpkg -s package
.
Pour vérifier si le paquet est installé:
- Shell: dpkg -s package | grep 'install ok installed'
ou si le paquet en attente ou d'autres états ne vous dérangent pas:
- Shell: dpkg -s package | grep 'installed'
Cette valeur revient à 0 une fois installé et à 1 sinon.
(Il est important d’utiliser le shell car nous utilisons un tuyau |
)
Je trouve en utilisant Shell ou le module de commande n'est pas "ansiblic".
Je préfère utiliser le module yum et le filtre json_query pour vérifier si un paquet est déjà installé. Par exemple. paquet httpd:
- yum:
list: httpd
register: Apache_service
- assert:
that:
- "'installed' in Apache_service|json_query('results[*].yumstate')"
msg: 'httpd is not installed'