ansible回调插件介绍(待完成)
简介
ansible回调插件(callback plugins)允许为事件添加一些额外响应。这里的事件包括了执行任务(task)的结果,例如(ok、failed、unreachable、skipped),以及执行剧本(playbook)的过程(start、hosts_matched、task_start、stats)等等。丰富的事件回调使得回调插件能够做非常多的事情,不过,大多数时候他们都用来提供各种各样的输出,或者将日志传输到日志采集器,又或者当遇到特定事件时触发某些特定的任务。
使用
配置项
回调插件的配置项与其他ansible配置项类似,既可以通过环境变量定义,也可以在ansible.cfg配置文件中定义,优先级顺序为:ANSIBLE_CONFIG --> ansible.cfg --> ~/.ansible.cfg --> /etc/ansible/ansible.cfg。
内置插件相关的配置项如下:
# 启用的回调插件
callbacks_enabled=<list>
# 回调插件默认搜寻路径
callback_plugins=~/.ansible/plugins/callback:/usr/share/ansible/plugins/callback
# 标准输出回调插件,可以运行多个回调插件,但只可以运行一个标准输出类型的回调插件
stdout_callback=default
内置插件示例
通过ansible-doc -t callback -l命令,能够列出所有可用的插件;通过ansible-doc -t callback <plugin name>命令能够查阅插件的描述与使用方式。
# ansible-doc -t callback -l
...
default                               default Ansible screen output
junit                                 write playbook output to a JUnit file
minimal                               minimal Ansible screen output
oneline                               oneline Ansible screen output
ovirt.ovirt.stdout                    Output the log of ansible
theforeman.foreman.foreman            Sends events to Foreman
tree                                  Save host events to files
# ansible-doc -t callback oneline
> ANSIBLE.BUILTIN.ONELINE    (/usr/local/lib/python3.9/site-packages/ansible/plugins/callback/oneline.py)
        This is the output callback used by the -o/--one-line command line option.
NAME: oneline
TYPE: stdout
VERSION_ADDED_COLLECTION: ansible.builtin
其中,default是ansible-playbook所使用的默认回调插件,我们运行ansible-playbook时看到的大部分输出都是运行这个插件的结果。
default回调插件示例:

minimal是ansible命令行(ad-hoc)的默认回调插件。修改stdout_callback=minimal后,输出结果如下:

oneline会将每个任务的输出限制为一行:

tree则会将执行的结果以json格式保存在指定目录中,目录默认为~/.ansible/tree,可通过callback_tree配置项修改。

这个网站很好的展示了所有内置回调插件的用法,包括svg视频和文本两种展示方式:Ansible Callback-Plugins (rndmh3ro.github.io)。
开发
ansible支持自定义回调插件,如果内置插件中没有自己想要的功能,那么可以自行开发插件以实现自己想要的功能。
一个回调插件即是一个python文件,其中定义了一系列特别的回调函数,在这些回调函数中编写自定义的代码,即可在ansible playbook执行到特定地方时调用这些代码,从而实现自己想要的功能。
ansible支持的回调函数均定义于ansible/plugins/callback/__init.py文件的CallbackBase类中,其所定义的回调函数非常丰富,却没有详尽的文档描述它们的作用,如果想要知道每个函数的触发点,需要自己查询源代码,希望这一段空缺以后能够补上。
经常用到的回调函数如下:
# task开始时执行
def v2_runner_on_start(self, host, task):
# task结束后执行(failed、ok、skipped、unreachable)
def v2_runner_on_failed(self, result, ignore_errors=False):
def v2_runner_on_ok(self, result):
def v2_runner_on_skipped(self, result):
def v2_runner_on_unreachable(self, result):
# playbook开始时执行
def v2_playbook_on_start(self, playbook):
# playbook结束时执行
def v2_playbook_on_stats(self, stats):
在执行playbook时,往往会遇到如下问题:当任务由于各种问题失败时,我们需要修复问题,然后再重新执行playbook,可是直接重新执行的话需要跑很长一段重复的步骤,而如果直接在失败的步骤开始的话,又有可能会有变量未定义的错误(定义变量的步骤没有执行)。这个时候,有一种折中的方案是在失败步骤所在的role重新执行,当playbook脚本逻辑规范得当时,这种方法能够保证在绝大多数步骤失败时得到恰当的解决。
每次人力寻找失败步骤所在的role耗时耗力,这种事情可以交给回调插件进行。如下自定义插件用来在任务失败时保存最后运行的role,以便于重新执行playbook时指定开始的任务。其中,当每个task开始时会保存当前运行的role以及此role的第一个task;当task失败时则会将role的第一个task保存在/tmp/ansible_failed_role文件中。
# ~/.ansible/plugins/callback/lastrole.py
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
    name: lastrole
    type: stdout
    short_description: store last role when playbook failed.
    version_added: historical
    description:
        - store last role to /tmp/ansible_failed_role when playbook failed.
'''
from ansible.plugins.callback import CallbackBase
from ansible import constants as C
class CallbackModule(CallbackBase):
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'aggregate'
    CALLBACK_NAME = 'lastrole'
    def __init__(self):
        self.task = None
        self.role = None
        self.role_first_task = None
        super(CallbackModule, self).__init__()
    def v2_playbook_on_task_start(self, task, is_conditional):
        self.task = task.get_name()
        if task._role:
            if task._role._role_name != self.role:
                self.role_first_task = self.task
            self.role = task._role._role_name
    def v2_runner_on_failed(self, result, ignore_errors=False):
        if ignore_errors==True:
            return
        with open('/tmp/ansible_failed_role','w') as f:
            f.write('%s\n'%(self.role_first_task))
将此文件保存在~/.ansible/plugins/callback/(或任一callback_plugins配置项中的搜寻路径)目录下,随后在callbacks_enabled配置项中追加lastrole插件,即可在playbook运行时调用该插件。
执行playbook失败后查看/tmp/ansible_failed_role文件。
# cat /tmp/ansible_failed_role
pre_deploy : get external ip
再次执行playbook时从此task开始。
ansible-playbook -i inventory/hosts.ini playbooks/setup.yml --start-at-task='pre_deploy : get external ip'
一般来说,在项目中都是由程序执行playbook,这时也可自行编写逻辑,将ansible_failed_role写入到数据库中,在执行playbook时判断并传入该参数,更为自动化。
附录
回调函数的调试
ansible通过TaskQueueManager的send_callback方法调用回调函数,在playbook的运行过程中有各种地方都调用了这个方法。如果想要快速地了解知道ansible playbook在运行中到底在何时调用了什么回调函数,可以通过在代码中添加debug信息的方式得知。
# ansible/executor/task_queue_manager.py
...
class TaskQueueManager:
    ...
    def send_callback(self, method_name, *args, **kwargs):
        # 添加debug信息
        print(f'* send_callback, method_name: {method_name} args: {args} kwargs: {kwargs}')
        ...
调试能够精确地得出各个回调函数的运行顺序,下图展示了主要回调函数的运行过程。

除此之外,有一个特别的回调函数为def v2_on_any(self, *args, **kwargs):,ansible调用任何回调函数之后,都会调用一次该函数,一般用于调试。
目前所有的回调函数:
def v2_on_any(self, *args, **kwargs):
def v2_runner_on_failed(self, result, ignore_errors=False):
def v2_runner_on_ok(self, result):
def v2_runner_on_skipped(self, result):
def v2_runner_on_unreachable(self, result):
def v2_runner_on_async_poll(self, result):
def v2_runner_on_async_ok(self, result):
def v2_runner_on_async_failed(self, result):
def v2_playbook_on_start(self, playbook):
def v2_playbook_on_notify(self, handler, host):
def v2_playbook_on_no_hosts_matched(self):
def v2_playbook_on_no_hosts_remaining(self):
def v2_playbook_on_task_start(self, task, is_conditional):
def v2_playbook_on_cleanup_task_start(self, task):
def v2_playbook_on_handler_task_start(self, task):
def v2_playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None, unsafe=None):
def v2_playbook_on_import_for_host(self, result, imported_file):
def v2_playbook_on_not_import_for_host(self, result, missing_file):
def v2_playbook_on_play_start(self, play):
def v2_playbook_on_stats(self, stats):
def v2_on_file_diff(self, result):
def v2_playbook_on_include(self, included_file):
def v2_runner_item_on_ok(self, result):
def v2_runner_item_on_failed(self, result):
def v2_runner_item_on_skipped(self, result):
def v2_runner_retry(self, result):
def v2_runner_on_start(self, host, task):
参考文档
[Callback plugins — Ansible Documentation](
ansible回调插件介绍(待完成)的更多相关文章
- jquery.form.js官方插件介绍Form插件,支持Ajax,支持Ajax文件上传
		jquery.form.js官方插件介绍Form插件,支持Ajax,支持Ajax文件上传 http://www.malsup.com/jquery/form/#getting-started [JQu ... 
- 【转】LiveWriter插入高亮代码插件介绍 基于SyntaxHighighter
		转自:http://www.cnblogs.com/yaoshiyou/archive/2009/11/25/1610901.html 插件介绍 辛苦了两人小时写日志不小心浏览器崩溃了,发誓以后一定记 ... 
- JMeter性能监测插件介绍(三)
		JMeter 性能监测插件介绍 压力测试过程中,能够随时对负载服务器的健康状况的把控是相当重要的,有了这些数据,我们才能准确分析出服务器负载瓶颈.JMeter 插件包现在能够支持服务器监控,可以在所有 ... 
- 【转载】Grunt常用插件介绍
		项目名称 grunt-contrib v0.8.0 项目地址 https://github.com/gruntjs/grunt-contrib 项目介绍 此项目是对grunt常用插件的集合,刚接触gr ... 
- 学习笔记——Maven实战(八)常用Maven插件介绍(下)
		我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven- compiler-plugin完成的.进一步说,每个任务对应 ... 
- Notepad++前端开发常用插件介绍 - BorisHuai前端修炼 - 博客频道 - CSDN
		Notepad++前端开发常用插件介绍 - BorisHuai前端修炼 - 博客频道 - CSDN.NET http://blog.csdn.net/borishuai/article/details ... 
- (转)jQuery LigerUI 插件介绍及使用之ligerTree
		一,简介 ligerTree的功能列表: 1,支持本地数据和服务器数据(配置data或者url) 2,支持原生html生成Tree 3,支持动态获取增加/修改/删除节点 4,支持大部分常见的事件 5 ... 
- ArcGIS快速制图插件介绍
		ArcGIS快速制图插件介绍 By 李远祥 作品背景 <快速制图插件增强版>在原有的<快速制图插件>基础上,加入植被乱序填充.生成立体楼快.等高线增强显示.一键导出地图和数据. ... 
- subline text3常用插件介绍
		常用插件介绍: html beautify(ctrl+shift+alt+f) 自动排版代码 Emmet 输入少量代码后摁Tab键,系统自动补全代码. AutoFileName 快速列出你想引用的文 ... 
随机推荐
- Nginx超时问题解决
			在 nginx.conf 中配置以下内容 ... http { ... server { # 这里表示upstream 的连接.读取.发送超时时间都是300秒 proxy_connect_timeou ... 
- python脚本将json文件生成C语言结构体
			1.引言 以前用过python脚本根据excel生成相关C语言代码,其实本质就是文件的读写,主要是逻辑问题,这次尝试将json文件生成C语言的结构体. 2.代码 这是一个json文件,生成这个结构体的 ... 
- Java 多线程:基础
			Java 多线程:基础 作者:Grey 原文地址: 博客园:Java 多线程:基础 CSDN:Java 多线程:基础 顺序.并行与并发 顺序(sequential)用于表示多个操作『依次』处理.比如把 ... 
- ElasticSearch介绍和基本用法(一)
			ElasticSearch 引言 1.在海量数据中执行搜索功能时,如果使用MySQL, 效率太低. 2.如果关键字输入的不准确,一样可以搜索到想要的数据. 3.将搜索关键字,以红色的字体展示. 介绍: ... 
- 璞华HawkEye平台助力乳品行业巨头在数字化转型中领“鲜”一步!
			中国乳制品的市场规模接近4,000亿.在今天,产业数字化正在帮助这个传统产业实现更高质量的发展. 乳品行业现状 随着乳品行业规模扩大,各工厂引进大量的专用设备,设备故障也随之增多.设备的突发故障极易造 ... 
- golang 实现笛卡尔积(泛型)
			背景 input: [[a,b],[c],[d,e]] output: [[a,c,d],[a,c,e],[b,c,d],[b,c,e]] 思路:分治 预处理第一项:[a,b] -> [[a], ... 
- 【gRPC】C++异步服务端客户端API实例及代码解析
			对于同步API而言,程序的吞吐量并不高.因为在每次发送一个gRPC请求时,会阻塞整个线程,必须等待服务端的ack回到客户端才能继续运行或者发送下一个请求,因此异步API是提升程序吞吐量的必要手段. g ... 
- 5.Ceph 基础篇 - 认证
			文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247485272&idx=1&sn=4b27c357 ... 
- 普通用户使用CI/CD权限使用
			根据文章:授权用户访问名称空间 (https://www.cnblogs.com/sanduzxcvbnm/p/15015576.html) 进行有关操作后,普通用户点击 会报错如下信息: 解决办法: ... 
- java基础-冒泡排序以及稀疏数组
			java基础 以下内容为本人的学习笔记,如需要转载,请声明原文链接 https://www.cnblogs.com/lyh1024/p/16720908.html Ø 冒泡排序原理: 比较数组中, ... 
