web-dev-qa-db-de.com

Ansible-Include-Task nur, wenn eine Datei vorhanden ist

Ich versuche, eine Datei nur einzuschließen, wenn sie existiert. Dies ermöglicht benutzerdefinierte "Aufgaben/Rollen" zwischen vorhandenen "Aufgaben/Rollen", wenn der Benutzer meiner Rolle dies benötigt. Ich habe das gefunden:

- include: ...
  when: condition

Die Ansible-Dokumente geben jedoch an, dass:

"Alle Aufgaben werden ausgewertet, aber die Bedingung wird auf jede Aufgabe angewendet" - http://docs.ansible.com/playbooks_conditionals.html#applying-when-to-roles-and-includes

So

- stat: path=/home/user/optional/file.yml
  register: optional_file
- include: /home/user/optional/file.yml
  when: optional_file.stat.exists

Wird fehlschlagen, wenn die enthaltene Datei nicht vorhanden ist. Ich denke, es gibt möglicherweise einen anderen Mechanismus, mit dem ein Benutzer einem vorhandenen Rezept Aufgaben hinzufügen kann. Ich kann nicht zulassen, dass der Benutzer eine Rolle nach meiner hinzufügt, weil er die Reihenfolge nicht kontrollieren kann: Ihre Rolle wird nach meiner ausgeführt.

28
Leito

Vielen Dank für Ihre Hilfe! Ich frage meine eigene Frage, nachdem ich endlich alle Antworten und den Code meiner eigenen Frage im heutigen Ansible ausprobiert habe: ansible 2.0.1.0

Mein ursprünglicher Code scheint jetzt zu funktionieren, mit der Ausnahme, dass sich die optionale Datei auf meinem lokalen Computer befand. Ich musste stat durch local_action ausführen und become: no für diese bestimmten Aufgaben festlegen in meinem lokalen Rechner und Fehler mit: "Sudo: ein Passwort ist erforderlich\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
10
Leito

Die with_first_found-Bedingung kann dies ohne stat oder local_action erreichen. Diese Bedingung durchläuft eine Liste lokaler Dateien und führt die Aufgabe mit item auf den Pfad der ersten vorhandenen Datei aus. Wenn Sie skip: true in die with_first_found-Optionen aufnehmen, wird verhindert, dass ein Fehler auftritt, wenn die Datei nicht vorhanden ist.

Beispiel:

- hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - include: "{{ item }}"
      with_first_found:
        - files:
            - /home/user/optional/file.yml
          skip: true
26
Dave Konopka

Ich benutze etwas anderes als das Dateimodul und was für mich der Trick war, nach der Variablendefinition zu suchen, versuche etwas wie

when: optional_file.stat.exists is defined and optional_file.stat.exists

die Task wird nur ausgeführt, wenn die Variable vorhanden ist.

5
olluch

Mit ansible-2.1.0 kann ich Schnipsel wie folgt in meinem Playbook verwenden:

- 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

Ich erhalte keine Fehler/Fehler, wenn local.yml nicht vorhanden ist und das Playbook ausgeführt wird (als Playbook, dh es beginnt mit der hosts:-Zeile usw.)

Sie können dasselbe auf Taskebene stattdessen mit ähnlichem Code ausführen. __ Die Verwendung von stat scheint richtig zu funktionieren.

2
Kayvan Sylvan

Ich könnte hier Zeit verbringen, um die Fehlerbehandlungsbestimmungen von bash ansible zu verbessern, aber kurz gesagt, Sie haben Recht und Sie können das stat-Modul aus angegebenen Gründen nicht für diesen Zweck verwenden.

Die einfachste Lösung für die meisten anpassbaren Probleme besteht darin, sie außerhalb des Bereichs ansprechbar zu machen. Z.B.

- 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_whenhinzugefügt, um zu verhindern, dass Host von weiteren Aufgaben ausgeschlossen wird, wenn die Datei nicht vorhanden ist.

2
Kashyap

Es gibt auch die Möglichkeit, einen Jinja2-Filter dafür zu verwenden:

 - set_fact: optional_file="/home/user/optional/file.yml"

 - include: ....
   when: optional_file|exists
1
mbarthelemy

Die beste Option, die ich bisher gefunden habe, ist folgende:

- include: "{{ hook_variable | default(lookup('pipe', 'pwd') ~ '/hooks/empty.yml') }}"

Es ist nicht genau ein "Wenn-existiert", aber es gibt den Benutzern Ihrer Rolle dasselbe Ergebnis. Erstellen Sie einige Variablen in Ihrer Rolle und eine leere Standarddatei. Die Jinja-Filter "default" und "lookup" sorgen dafür, dass auf die leere Datei zurückgegriffen wird, falls die Variable nicht gesetzt wurde.

Zur Vereinfachung kann ein Benutzer die {{ playbook_dir }}-Variable zum Festlegen der Pfade verwenden:

hook_variable: "{{ playbook_dir }}/hooks/tasks-file.yml" 
1

Wenn ich mich nicht geirrt habe, willst du das Spielbuch fortsetzen, auch wenn die Aussage falsch ist?

Wenn ja, fügen Sie diese Zeile bitte nach when: hinzu.

ignore_errors: True

So werden Ihre Aufgaben so aussehen:

- stat: path=/home/user/optional/file.yml
  register: optional_file
- include: /home/user/optional/file.yml
  when: optional_file.stat.exists
  ignore_errors: True

Bitte lassen Sie mich wissen, wenn ich Ihre Frage richtig verstanden habe oder weiterhelfen kann. Vielen Dank

1
Arbab Nazar