#! /usr/bin/env python # -*- coding: utf-8 -*- import os import re import subprocess import sys from ansible.callbacks import display, banner class CallbackModule(object): """Makes sure Ansible is not out of date with branch. Requires ansible-playbook command to be ran in locally cloned location. """ # env_var_name = 'IGNORE_OUTDATED_GIT_BRANCH' msg_out_of_sync = 'OUTDATED GIT BRANCH: Your git branch is out of sync with the ' \ 'remote branch. Please update your branch (git pull) before continuing. ' \ #' or skip this test by setting the environment ' \ # 'variable {0}=yes.'.format(env_var_name) msg_not_in_git = 'Get inside the git repository, duh!' msg_local_changes = 'You have local changes. Please consider committing them before running the playbook.' ######### out_of_sync_re = re.compile(r'Your branch (is behind|and .* have diverged)', re.MULTILINE) local_changes = re.compile(r'Changes not staged for commit', re.MULTILINE) ########## def playbook_on_start(self): try: subprocess.check_output(['git pull'], shell=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: pass try: cmnd_output = subprocess.check_output(['git status'], shell=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as exc: if exc.returncode == 128: # Git returns error code 128 when not inside the git repo display(banner(self.msg_not_in_git), color='bright green') sys.exit(1) else: if self.local_changes.search(cmnd_output): display(banner(self.msg_local_changes), color='bright red') if self.out_of_sync_re.search(cmnd_output): display(banner(self.msg_out_of_sync), color='bright blue') sys.exit(1)