Aktualisiert
Als ich meine Antwort zum ersten Mal geschrieben habe (2014-02-27), hatte Ansible keine eingebaute Unterstützung dafür, eine Aufgabe nur einmal pro Playbook auszuführen, nicht einmal pro betroffenem Host, auf dem das Playbook ausgeführt wurde. Der Support dafür wurde jedoch, wie tlo schreibt, mit run_once: true
in Ansible-Version 1.7.0 (veröffentlicht am 2014-08-06) eingeführt. Mit dieser Funktion sollte die Beispielaufgabendefinition aus der Frage wie folgt geändert werden:
- name: Stellen Sie sicher, dass das lokale Git-Repository aktuell ist
local_action: git pull
run_once: true
register: command_result
failed_when: "'Updating' in command_result.stdout"
um das Gewünschte zu erreichen.
Ursprüngliche Antwort
[Die folgende Antwort war meine vorgeschlagene Lösung für das spezielle Problem sicherzustellen, dass der lokale Git-Zweig aktualisiert ist, bevor Ansible die Aufgaben eines Playbooks ausführt.]
Ich habe das folgende Ansible-Callback-Plugin geschrieben, das die Ausführung des Playbooks vermeidet, wenn der aktuelle Git-Zweig nicht mit dem Remote-Zweig synchron ist (entweder zurückliegt oder sich davon entfernt hat). Um es zu verwenden, platzieren Sie den folgenden Code in einer Datei wie callback_plugins/require_updated_git_branch.py
in Ihrem übergeordneten Ansible-Playbook-Verzeichnis:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import os
import re
import subprocess
import sys
from ansible.callbacks import display, banner
class CallbackModule(object):
"""Macht Ansible erforderlich, dass der aktuelle Git-Zweig auf dem neuesten Stand ist.
"""
env_var_name = 'IGNORE_OUTDATED_GIT_BRANCH'
msg = 'ÜBERHOLTER GIT-ZWEIG: Ihr Git-Zweig ist nicht mit dem ' \
'Remote-Zweig synchron. Bitte aktualisieren Sie Ihren Zweig (git pull), bevor ' \
'Sie fortfahren, oder überspringen Sie diesen Test, indem Sie die Umgebungsvariable ' \
'{0}=yes setzen.'.format(env_var_name)
out_of_sync_re = re.compile(r'Ihr Zweig (liegt zurück|und .* haben sich getrennt)',
re.MULTILINE)
def __init__(self, *args, **kwargs):
if os.getenv(self.env_var_name, 'no') == 'yes':
self.disabled = True
def playbook_on_start(self):
subprocess.call(['git', 'fetch'])
if self.out_of_sync_re.search(subprocess.check_output([
'git', 'status', '--untracked-files=no'])):
display(banner(self.msg), color='bright purple')
sys.exit(1)
Zum Beispiel hält der Befehl ansible-playbook site.yml
früh an, wenn der lokale Zweig hinter dem Remote-Zweig liegt, mit dem folgenden Output:
__________________________________________________________
/ ÜBERHOLTER GIT-ZWEIG: Ihr Git-Zweig ist nicht mit \
| dem Remote-Zweig synchron. Bitte aktualisieren Sie Ihren \
| Zweig (git pull) bevor Sie fortfahren, oder überspringen \
\ Sie diesen Test, indem Sie die Umgebungsvariable IGNORE_OUTDATED_GIT_BRANCH=yes setzen. /
----------------------------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Und, wie die Kuh vorschlägt, um diese Überprüfung auszuschalten, können Sie den Befehl wie folgt ausführen:
$ IGNORE_OUTDATED_GIT_BRANCH=yes ansible-playbook site.yml
Diese Lösung löst nicht das allgemeine Problem, das jede Ansible-Aufgabe nur einmal ausgeführt wird, unabhängig von der Anzahl der beteiligten Hosts, stellt jedoch sicher, dass veraltete Playbooks nicht ausgeführt werden, und behandelt die von Ihnen erwähnte Sorge bezüglich meines aliasbasierten Vorschlags.