2014-02-19 6 views

Antwort

54

Ich glaube nicht, dass das Yum-Modul in diesem Fall helfen würde. Es hat derzeit 3 ​​Zustände: abwesend, aktuell und aktuell. Da es so klingt, als ob Sie das Paket nicht installieren oder entfernen möchten (zumindest an dieser Stelle), müssen Sie dies in zwei manuellen Schritten tun. Die erste Aufgabe würde prüfen, ob das Paket existiert, dann würde die zweite Aufgabe einen Befehl basierend auf der Ausgabe des ersten Befehls aufrufen.

Wenn Sie „rpm -q“ verwenden, um zu überprüfen, ob ein Paket wie dies die Ausgabe für ein Paket besteht dann aussehen würde, die es gibt:

# rpm -q httpd 
httpd-2.2.15-15.el6.centos.1.x86_64 

und wie diese, wenn das Paket nicht existiert:

# rpm -q httpdfoo 
package httpdfoo is not installed 

So Ihre ansible Aufgaben würde wie folgt aussehen:

- 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 

Der Befehl rpm wird auch Ausfahrt mit einer 0, wenn das Paket vorhanden ist, oder 1, wenn das Paket nicht gefunden wird, so ist eine weitere Möglichkeit zu nutzen:

when: rpm_check.rc == 1 
+8

Das Problem mit dem Befehl ist, wenn 'rp -q' mit 0 (kein Paket gefunden) beendet wird, wird das Playbook fehlschlagen. Um zu verhindern, dass append: 'ignore_errors: True 'an die Aufgabe anlegt, um die Ausgabe in nachfolgenden Aufgaben zu verwenden, um die rpm zu installieren. – romanofski

+3

Zusätzlich können Sie 'changed_when: no 'hinzufügen, um zu erzwingen, dass das' command' Modul nicht sagt, dass etwas geändert wurde. – Alicia

+3

Um die Fehlermeldung zu vermeiden, wenn das Paket nicht gefunden wird, können Sie 'failed_when: rpm_check.rc> 1' setzen. – Alicia

25

Basierend auf der Bruce P Antwort oben, einen ähnlichen Ansatz für apt/deb-Dateien ist

- 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 
+1

Ich musste 'failed_when: False' hinzufügen –

+1

Ich möchte darauf hinweisen, dass das apt-Modul ab Ansible 2.1 eine Option namens 'only_upgrade' hat, die genau für dieses Ziel entwickelt wurde. Die Dokumentation beschreibt den Schalter: "Installieren/aktualisieren Sie nur ein Paket, wenn es bereits installiert ist." – Erathiel

+2

@Ethathiel Ich denke, was dieses Spielbuch löst, ist eine "bestimmte" Aufgabe, wenn das gegebene Paket gefunden wird. Also nicht unbedingt ein fehlendes Paket installieren, es könnte etwas anderes sein. Diese 'only_upgrade'-Option stellt sicher, dass das Paket entweder installiert oder aktualisiert wird, ähnlich wie bei 'state'. – JohnnyQ

23

In Verbindung damit.

Putting alles zusammen, komplette Textbuch für Debian (Ubuntu), welche Updates Paket nur, wenn es bereits installiert ist:

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

Leider ansible noch nicht eingebaute Unterstützung für einfaches Paket Aktualisierung zu machen, finden Sie ab: https://github.com/ansible/ansible/issues/10856

+1

Wie [unten] (https://StackOverflow.com/a/36405647/2192488), ist die Verwendung von 'shell: dpkg --status {{package}} | grep 'install ok installiert'' robuster als die Verwendung von 'command : dpkg-query -l {{Paket}} '. –

8

Sie sollten dpkg -l package nicht verwenden, da es keine Ahnung hat, ob Ihr Paket entfernt wurde oder noch installiert ist.
Stattdessen ist es wahrscheinlich besser, dpkg -s package zu verwenden.

Um zu überprüfen, ob das Paket installiert ist:
- shell: dpkg -s package | grep 'install ok installed'
oder wenn Sie das Paket in die Warteschleife oder anderen Staaten nichts dagegen:
- shell: dpkg -s package | grep 'installed'
Diese Rückkehr 0 bei der Installation und 1, wenn nicht.

(Es ist wichtig, um die Schale zu verwenden, da wir ein Rohr verwenden |)

7

Wenn das Paket durch das System Paket-Manager installiert ist (yum, apt, etc.) selbst, dann können Sie nutzen den Check machen Modus-Flag von ansible, um den Installationsstatus zu registrieren, ohne das Paket tatsächlich zu installieren.

- 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 
+4

Durch die Verwendung des "Paket" -Moduls anstelle des spezifischen 'yum'-Elements würde dies die beste Antwort sein, da es an mehr als RHEL- oder Debian-Linux-Distributionen arbeiten würde. Gut gemacht! – Huygens

+1

Angepasst, danke für das Feedback @Huygens – reegnz

+0

Das hat nicht für mich funktioniert. Wenn das Paket nicht installiert ist, wird Ansible nicht ausgeführt. Ich musste "ignore_errors: yes" zum Abschnitt "Check if package is installed" hinzufügen. –

1

Ich finde mit Shell oder Befehlsmodul ist nicht "ansiblic".

Ich bevorzuge mit yum Modul und json_query Filter zu überprüfen, ob ein Paket bereits installiert ist. Z.B. httpd-Paket:

Verwandte Themen