web-dev-qa-db-fra.com

Comment obliger Ansible à exécuter un script Shell si un package n'est pas installé

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?

54
Kimble

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
67
Bruce P

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
29
Kevin Carmody

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

23
arma

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 
20
reegnz

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.

13
sduthil

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

9
corentingi

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'
1
Mqll