In meinem Ansible-Playbook habe ich Folgendes:
- name: "A: Check to see if we need to run task B"
[... implementation omitted, not relevant ...]
register: task_a_result
check_mode: no # even run in check mode
changed_when: no # this only reads/checks stuff
- name: "B: Write x to file"
shell: "echo {{ my_var|quote }} > /path/to/file"
when: task_a_result.stdout_lines[0].startswith('ABCDEF')
changed_when: yes # when run, it always changes the state
Ich tuenichtmöchte B im Prüfmodus ausführen (deshalb kein check_mode: no
), aber ich möchteBerichtes wäre anders, wenn es im Nicht-Check-Modus ausgeführt worden wäre. Ich möchte dieses Verhalten, weilIch möchte keine Überraschungen erleben, wenn ich im Nicht-Check-Modus arbeite. Obwohl ich changed_when: yes
selbst eine Bedingung festgelegt habe, zeigt Ansible die Aufgabe immer alsübersprungenund somitunverändertmir:
skipping: [myhost] => changed=false msg: skipped, running in check mode
(Das Obige im Prüfmodus, und im normalen Nicht-Prüfmodus wird „geändert“ gemeldet.)
Ich habe diesen Fehlerbericht gefunden, der anscheinend falsch interpretiert und unangemessen geschlossen wurde:14950, aber dazu kann ich keinen weiteren Kommentar abgeben.
Übersehe ich etwas Grundlegendes? Andere Module melden in Ansible normalerweise problemlos den Status „hätte sich geändert“, aber ist dies auch für Shell/Befehl möglich?
Die Verwendung von Ansible 2.7.12 und 2.8.2 führt zu denselben Ergebnissen.
Ich hoffe, böse Hacks im Befehl selbst zu vermeiden, wie:
- name: "B: Write x to file"
shell: "echo {{ my_var|quote }} {{ '>' if task_a_result.stdout_lines[0].startswith('ABCDEF') else '' }} /path/to/file"
when: task_a_result.stdout_lines[0].startswith('ABCDEF')
changed_when: yes
Und ja, ich weiß, dass ich mit den Kopier-/Vorlagenmodulen in eine Datei schreiben kann, aber ich kann anscheinend nichtüberschreibenDateien damit, z. B. echo 1234 > /sys/module/zfs/parameters/zfs_arc_max
, weil copy/template anscheinend versuchen würde, die Datei zu ersetzen, und das Setzen eines Kernelparameters würde so nicht funktionieren. Und nein, dieser Kernelmodulparameter wird unter Linux nicht über sysctl verfügbar gemacht.
Antwort1
Ich weiß, das ist schon etwas älter, aber ich suche nach einer Lösung für dieses Problem. Außerdem habe ich die Überraschungen mit dem Befehlsmodul als OP satt.
Was wäre, wenn wir den „Befehls“-Teil so ändern würden, dass er im Prüfmodus einen anderen Befehl ausführt? Und wir führen die Aufgabe immer aus, auch im Prüfmodus.
Hinweis: Bevor Sie sich beschweren, ich weiß, dass dies ein schlechtes Beispiel ist. Ich weiß, dass es im Modul „Befehl“ eine Option zum Erstellen gibt. Dies soll nur ein Beispiel sein.
Dies ist meine bisherige Lösung:
- name: Get some info
stat: {path: /tmp/somefile}
register: file_info
- name: Run the command conditionally
command:
"{{ 'true' if (file_info['stat']['exists'] or ansible_check_mode)
else 'touch /tmp/somefile' }}"
changed_when: not file_info['stat']['exists']
check_mode: false
Es funktioniert, ist aber aufgebläht.
Bitte sagen Sie mir, ob es bessere Lösungen gibt.
Antwort2
Ich habe ein ähnliches Bedürfnis. Ich möchte sehen, ob der Befehl ausgeführt wird, damit ich keine Überraschungen erlebe, wenn er nicht im Prüfmodus ausgeführt wird.
Als Workaround habe ich eine Debug-Aufgabe hinzugefügt, die meldet, dass es eine Änderung geben wird und habe die „Wann“-Bedingung der Befehlsaufgabe verwendet, um „changed_when“ für die Debug-Aufgabe festzulegen, d. h.
- name: "Report pending change"
debug:
msg: "Change pending"
changed_when: task_a_result.stdout_lines[0].startswith('ABCDEF')
when: ansible_check_mode|bool