From: Zack Cerza Date: Wed, 2 Mar 2016 22:08:38 +0000 (-0700) Subject: Adapt failure_log plugin to work with ansible 2.0 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F205%2Fhead;p=ceph-cm-ansible.git Adapt failure_log plugin to work with ansible 2.0 This commit maintains backward compatibility Signed-off-by: Zack Cerza --- diff --git a/callback_plugins/failure_log.py b/callback_plugins/failure_log.py index 78ddbfcf..e0c62238 100644 --- a/callback_plugins/failure_log.py +++ b/callback_plugins/failure_log.py @@ -5,14 +5,21 @@ or logging. A log will not be written unless the environment variable ANSIBLE_FAILURE_LOG is present and contains a path to a file to write the log to. - -NOTE: This plugin was only tested on ansible version 1.9.2 and does not support -v2 style plugins """ import yaml import os import logging +import ansible +ANSIBLE_MAJOR = int(ansible.__version__.split('.')[0]) + +if ANSIBLE_MAJOR >= 2: + from ansible.parsing.yaml.objects import AnsibleUnicode + from ansible.plugins.callback import CallbackBase as callback_base +else: + callback_base = object + + log = logging.getLogger(__name__) # We only want to log if this env var is populated with # a file path of where the log should live. @@ -31,27 +38,51 @@ def log_failure(host, result): if fail_log: failure = {"{0}".format(host): dict()} failure[host] = result + if ANSIBLE_MAJOR >= 2: + failure = sanitize_dict(failure) log.error(yaml.safe_dump(failure)) -class CallbackModule(object): +def sanitize_dict(obj): + """ + Replace AnsibleUnicode objects with strings to avoid RepresenterError when + dumping to yaml + + Only needed in ansible >= 2.0 + """ + for key in obj.keys(): + value = obj[key] + if isinstance(value, AnsibleUnicode): + value = str(value) + obj[key] = value + elif isinstance(value, dict): + value = sanitize_dict(value) + obj[key] = value + return obj + + +class CallbackModule(callback_base): """ This Ansible callback plugin writes task failures to a yaml file. """ + CALLBACK_VERSION = 2.0 + CALLBACK_TYPE = 'notification' + CALLBACK_NAME = 'failure_log' def runner_on_failed(self, host, result, ignore_errors=False): """ A hook that will be called on every task failure. """ - if ignore_errors: return - - log_failure(host, result) + try: + log_failure(host, result) + except: + import traceback + traceback.print_exc() def runner_on_unreachable(self, host, result): """ A hook that will be called on every task that is unreachable. """ - log_failure(host, result)