Ansible的handler

环境

  • 管理节点:Ubuntu 22.04
  • 控制节点:CentOS 8
  • Ansible:2.15.6

handler

当任务结果产生变化时,通过 notify 通知handler做相应处理。

一个简单例子

---
- hosts: alltasks:- name: task1debug:msg: "I am task1"changed_when: truenotify:- handler1handlers:- name: handler1debug:msg: "I am handler1"

运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task1"
}RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler1"
}

注意:只有task产生变化时,才会触发notify。由于debug语句不产生变化,所以指定 changed_when: true ,强制task1产生变化。

一个复杂例子

---
- hosts: alltasks:- name: task1debug:msg: "I am task1"- name: task2debug:msg: "I am task2"changed_when: truenotify:- handler2- handler1- name: task3debug:msg: "I am task3"handlers:- name: handler1debug:msg: "I am handler1"- name: handler2debug:msg: "I am handler2"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "I am task1"
}TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task2"
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "I am task3"
}RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler1"
}RUNNING HANDLER [handler2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler2"
}

可见:

  1. 一个task可以nofiy多个handler
  2. 多个handler的运行顺序和notify时的顺序无关,只和handler本身的顺序有关(本例中,notify的顺序是handler2在handler1之前,但运行时是按handler本身的顺序,handler1在handler2之前)
  3. handler在所有task运行结束之后才运行(本例中,task2 notify了handler,但handler是在task3之后才运行的)
---
- hosts: alltasks:- name: task1debug:msg: "I am task1"changed_when: truenotify:- handler1- name: task2debug:msg: "I am task2"changed_when: truenotify:- handler1handlers:- name: handler1debug:msg: "I am handler1"

运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task1"
}TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task2"
}RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler1"
}

可见,若多个task notify同一个handler,该handler只会运行一次。

通过 listen 匹配topic

前面的例子,在notify时,是通过handler的 name 来匹配topic的。也可以通过handler的 listen 来匹配:

---
- hosts: alltasks:- name: task1debug:msg: "I am task1"changed_when: truenotify:- task1 changed- name: task2debug:msg: "I am task2"changed_when: truenotify:- task2 changedhandlers:- name: handler1debug:msg: "I am handler1"listen:- "task2 changed"- "task1 changed"

运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task1"
}TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task2"
}RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler1"
}

可见,通过 listen ,一个handler可以监听多个nofiy的topic。

考一考

下面的play,运行结果是什么?

---
- hosts: alltasks:- name: task1debug:msg: "I am task1"changed_when: truenotify:- task1 changed- name: task2debug:msg: "I am task2"changed_when: truenotify:- task2 changedhandlers:- name: handler1debug:msg: "I am handler1"listen: "task2 changed"- name: handler2debug:msg: "I am handler2"listen:- "task2 changed"- "task1 changed"- name: handler3debug:msg: "I am handler3"listen: "task1 changed"

答:运行结果为:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task1"
}TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task2"
}RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler1"
}RUNNING HANDLER [handler2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler2"
}RUNNING HANDLER [handler3] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler3"
}

立即运行handler

前面提到,handler是在所有task运行结束后才运行的。如果想要立即运行handler,可用 meta: flush_handlers

---
- hosts: alltasks:- name: task1debug:msg: "I am task1"changed_when: truenotify: handler2- name: flushmeta: flush_handlers- name: task2debug:msg: "I am task2"changed_when: truenotify: handler1- name: task3debug:msg: "I am task3"handlers:- name: handler1debug:msg: "I am handler1"- name: handler2debug:msg: "I am handler2"

运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task1"
}TASK [flush] ***************************************************************************************RUNNING HANDLER [handler2] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler2"
}TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task2"
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => {"msg": "I am task3"
}RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler1"
}

可见,flush之后,handler2立即运行了,而handler1则是在所有task都运行结束之后才运行的。

注意:flush触发运行的handler,如果随后又被notify,还会再次运行:

---
- hosts: alltasks:- name: task1debug:msg: "I am task1"changed_when: truenotify: handler1- name: flushmeta: flush_handlers- name: task2debug:msg: "I am task2"changed_when: truenotify: handler1handlers:- name: handler1debug:msg: "I am handler1"

运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task1"
}TASK [flush] ***************************************************************************************RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler1"
}TASK [task2] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task2"
}RUNNING HANDLER [handler1] *************************************************************************
ok: [192.168.1.55] => {"msg": "I am handler1"
}

可见,handler1运行了两次。

handler的命名最好不要包含变量

---
- hosts: allvars:var1: "aaa"tasks:- name: task1debug:msg: "I am task1"changed_when: truenotify: handler {{ var1 }}handlers:- name: handler {{ var1 }}debug:msg: "I am handler1"

运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => {"msg": "I am task1"
}RUNNING HANDLER [handler aaa] **********************************************************************
ok: [192.168.1.55] => {"msg": "I am handler1"
}

没有问题。但是,这里有个潜在的问题:

---
- hosts: all#vars:#  var1: "aaa"tasks:- name: task0set_fact:var1: "aa"- name: task1debug:msg: "I am task1"changed_when: truenotify: handler {{ var1 }} # 可以识别handlers:- name: handler {{ var1 }} # 无法识别debug:msg: "I am handler1"

运行结果如下:

TASK [task0] ***************************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
[WARNING]: Handler 'handler {{ var1 }}' is unusable because it has no listen topics and the name
could not be templated (host-specific variables are not supported in handler names). The error:
'var1' is undefined. 'var1' is undefined
ERROR! The requested handler 'handler aa' was not found in either the main handlers list nor in the listening handlers list

可见,对于动态定义的变量,notify可以识别,而handler命名处无法识别(未定义)。

类似的,如果已定义的变量,如果动态改变其值,notify可以识别,而handler命名处仍然是原值。

所以,最好不要在handler命名处使用变量。

参考

  • https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/172434.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++初阶】二、入门知识讲解(引用、内联函数、auto关键字、基于范围的for循环、指针空值nullptr)

相关代码gitee自取: C语言学习日记: 加油努力 (gitee.com) 接上期: 【C初阶】一、入门知识讲解 (C关键字、命名空间、C输入&输出、缺省参数、函数重载)-CSDN博客 六 . 引用 (1). 引用的概念和特性…

Hugging Face宣布最受欢迎的AI机构,开源模型ChatGLM-6B广受认可

近日,Hugging Face作为开源AI社区的代表,总结了社区最欢迎的前15个公司和机构,几乎囊括了全部国内外风头正盛的AI科技机构,Stability AI、Meta AI、Runway占据排名前三,大众熟知的OpenAI、谷歌、微软也榜上有名。 其中…

医学检验(LIS)管理系统源码,LIS源码,云LIS系统源码

医学检验(LIS)管理系统源码,云LIS系统全套商业源码 随着全自动生化分析仪、全自动免疫分析仪和全自动血球计数器等仪器的使用,检验科的大多数项目实现了全自动化分析。全自动化分析引入后,组合化验增多,更好的满足了临床需要&…

php订单发起退款(余额和微信支付)

index.html <a class"btn btn-danger btn-change btn-tuikuan btn-disabled" href"javascript:;"><i class"fa fa-tuikuan"></i> 订单退款</a>-->order.js // 为表格绑定事件Table.api.bindevent(table);//退款按钮…

K8S----taint、tolerations、label

一、污点(taint),针对的是节点,只有node才有污点的概念 1、 给节点增加一个污点 kubectl taint nodes node1 key1=value1:NoSchedule给节点 node1 增加一个污点,它的键名是 key1,键值是 value1,效果是 NoSchedule。 这表示只有拥有和这个污点相匹配的容忍度的 Pod 才能…

056-第三代软件开发-软件打包

第三代软件开发-软件打包 文章目录 第三代软件开发-软件打包项目介绍软件打包1 下载 linuxdepoyqt 工具2 安装 linuxdepoyqt3 qmake配置4 打包程序 总结 关键字&#xff1a; Qt、 Qml、 linuxdeployqt、 Ubuntu、 AppImage 项目介绍 欢迎来到我们的 QML & C 项目&…

本地运行“李开复”的零一万物 34B 大模型

这篇文章&#xff0c;我们来聊聊如何本地运行最近争议颇多的&#xff0c;李开复带队的国产大模型&#xff1a;零一万物 34B。 写在前面 零一万物的模型争议有很多&#xff0c;不论是在海外的社交媒体平台&#xff0c;还是在国内的知乎和一种科技媒体上&#xff0c;不论是针对…

C#中警告CA1050、CA1821、CA1822、CA1859、CA2249及处理

目录 一、CA1050警告及处理 1.如何解决冲突&#xff1a; 2.何时禁止显示警告&#xff1a; 二、CA1821警告及处理 三、CA1822警告及处理 四、CA1859警告及处理 1.警告解决之前 2.警告解决之后 3.解决办法 1.警告解决之前 2.警告解决之后 3.解决办法 五、CA2249警告…

基恩士软件的基本操作(五,日志记录与使用)

目录 基恩士是如何保存日志的&#xff1f; 如何使用日志功能 查看DM10的值1秒加1的记录日志 设定id与储存位置 软元件设定&#xff08; 日志ID有10个&#xff08;0~10&#xff09;&#xff0c;每一个ID最多添加512个软元件&#xff09; 设定触发 执行日志的梯形图程序 触…

【Amazon】在Amazon EKS集群中安装部署最小化KubeSphere容器平台

文章目录 一、准备工作二、部署 KubeSphere三、访问 KubeSphere 控制台四、安装Amazon EBS CSI 驱动程序4.1 集群IAM角色建立并赋予权限4.2 安装 Helm Kubernetes 包管理器4.3 安装Amazon EBS CSI 驱动程序 五、常见问题六、参考链接 一、准备工作 Kubernetes 版本必须为&…

i社为什么不出游戏了?

I社&#xff0c;即国际知名的游戏公司&#xff0c;近来为何鲜有新游问世&#xff1f;曾经风靡一时的游戏开发者&#xff0c;如今为何陷入了沉寂&#xff1f;这其中的种种原因&#xff0c;值得我们深入剖析。 首先&#xff0c;I社近期的沉寂可能与其内部管理层的调整和战略规划…

Scrum敏捷开发培训团队和组织来说的重要性

Scrum敏捷开发培训对于团队和组织来说是至关重要的&#xff0c;有以下几点&#xff0c;大家可以参考下&#xff1a; 理解敏捷价值观和原则&#xff1a; 培训有助于团队理解敏捷方法背后的核心理念和价值观&#xff0c;包括个体和互动、工作软件、客户合作和响应变化。这有助于建…

RESTful API 架构快速入门 Flask实现

RESTful 简介 1.1 为什么要使用 RESTful 架构&#xff1f; Representational State Transfer&#xff08;REST&#xff09;是一种面向资源的架构风格&#xff0c;广泛应用于网络服务的设计和开发。使用RESTful架构有以下几个优点&#xff1a; 简单性和可扩展性&#xff1a; RE…

[LaTex]arXiv投稿攻略——jpg/png转pdf

一、将图片复制进ppt&#xff0c;右键单击图片选择设置图片格式&#xff0c;获取图片高度和宽度 二、选择“设计-幻灯片大小-自定义幻灯片大小” 三、设置幻灯片大小为图片大小 四、 选择“最大化” 五、 检查幻灯片大小是否与图像大小一致 六、导出为PDF

浅谈Python中的鸭子类型和猴子补丁

文章目录 前言一、鸭子类型二、猴子补丁关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 前言 Python 开发者可能…

C++变量、函数、类的声明和定义

参考文章&#xff1a;C中的类——类的定义和声明_c类的声明-CSDN博客 声明&#xff1a;向程序表明类型和名字&#xff0c;可以声明多次&#xff1b; 定义&#xff1a;分配存储空间&#xff0c;只能定义一次&#xff08;有了定义&#xff0c;可以省略声明&#xff09;&#xf…

进程并发-信号量经典例题-面包师问题

1 题目描述 面包师有很多面包和蛋糕&#xff0c;由N个销售人员销售。每个顾客进店后先取一个号&#xff0c;并且等着叫号。当一个销售人员空闲下来&#xff0c;就叫下一个号。试用信号量的P、V操作设计该问题的同步算法&#xff0c;给出所用共享变量&#xff08;如果需要&…

springboot打印启动信息

打印启动信息 转载自:www.javaman.cn 1 spring Bean实例化流程 基本流程&#xff1a; 1、Spring容器在进行初始化时&#xff0c;会将xml或者annotation配置的bean的信息封装成一个BeanDefinition对象&#xff08;每一个bean标签或者bean注解都封装成一个BeanDefinition对象&a…

【Vulnhub靶机】Jarbas--Jenkins

文章目录 信息收集主机发现端口扫描目录爆破 漏洞探测whatwebhash-identifierwhatweb 文档说明&#xff1a;https://www.vulnhub.com/entry/jarbas-1,232/ 靶机下载&#xff1a;Download (Mirror): 信息收集 主机发现 扫描C段 sudo nmap -sn 10.9.75.0/24端口扫描 sudo nma…

装饰者设计模式

package com.jmj.pattern.decorator;/*** 快餐类(抽象构建角色)*/ public abstract class FastFood {private float price;private String desc;public float getPrice() {return price;}public void setPrice(float price) {this.price price;}public String getDesc() {retu…