描述

  幂等性是在实际应用中经常需要考虑的概念,尤其是运维中。相较于将幂等性理解为各种异常情况的综合处理,将其理解为执行时需要考虑到在前次执行产生的影响的情况下能够正常执行则会更加容易接近业务需求。

  ansible包含众多的模块,大部分内置模块都能够保证操作的幂等性,即相关操作的多次执行能够达到相同结果这一特性,不会出现多次执行带来副作用的影响。但是也有不满足幂等原则的,比如shell模块、raw模块、command模块。

幂等操作和非幂等操作的对比

场景说明:

比如实现删除一个临时性的文件/root/testfile的操作,如果希望其在相同的条件下,多次执行能够保持相同的结果和不会带来其它副作用,至少需要保证此操作在/root/testfile文件存在和不存在的情况下都能正常动作。

# 当采用raw模块执行shell命令删除文件,第一次删除是成功,当执行第二次删除也是成功的,但是在生产环境这结果是不理想的,比如重启一个服务,你会随便重复重启吗?

[root@Server-1~]# touch /root/testfile
[root@Server-1~]# ansible localhost -m shell -a "rm -rf testfile"
localhost | CHANGED | rc=0 >>
[root@Server-1~]# ansible localhost -m shell -a "rm -rf testfile"
localhost | CHANGED | rc=0 >>

# 当采用file 模块执行删除文件,第一次执行删除文件成功changed: true,多次执行删除文件都是同一样的结果,不会带来副作用的影响changed: Fasle

[root@Server-1~]# touch /root/testfile
[root@Server-1~]# ansible localhost -m file -a "path=/root/testfile state=absent"
localhost | CHANGED => {
"changed": true,
"path": "/root/testfile",
"state": "absent"
}
[root@Server-1~]# ansible localhost -m file -a "path=/root/testfile state=absent"
localhost | SUCCESS => {
"changed": false,
"path": "/root/testfile",
"state": "absent"
}
贴上file模块absent时文件实现的幂等(中文注释)

vim /usr/lib/python2.7/site-packages/ansible/modules/files/file.py
.....
def get_state(path):
''' Find out current state ''' b_path = to_bytes(path, errors='surrogate_or_strict')
try:
if os.path.lexists(b_path): # 如果文件存在返回file,文件不存在返回absent
if os.path.islink(b_path):
return 'link'
elif os.path.isdir(b_path):
return 'directory'
elif os.stat(b_path).st_nlink > 1:
return 'hard' # could be many other things, but defaulting to file
return 'file' return 'absent'
except OSError as e:
if e.errno == errno.ENOENT: # It may already have been removed
return 'absent'
else:
raise def ensure_absent(path):
b_path = to_bytes(path, errors='surrogate_or_strict')
prev_state = get_state(b_path) # 获取文件的状态
result = {} if prev_state != 'absent': # 当prev_state='directory' or 'file' 为真
diff = initial_diff(path, 'absent', prev_state) if not module.check_mode:
if prev_state == 'directory': # 如果prev_state='directory', 则删除目录
try:
shutil.rmtree(b_path, ignore_errors=False)
except Exception as e:
raise AnsibleModuleError(results={'msg': "rmtree failed: %s" % to_native(e)})
else:
try:
os.unlink(b_path) # 如果prev_state='file', 则删除文件
except OSError as e:
if e.errno != errno.ENOENT: # It may already have been removed
raise AnsibleModuleError(results={'msg': "unlinking failed: %s " % to_native(e),
'path': path}) result.update({'path': path, 'changed': True, 'diff': diff, 'state': 'absent'}) # 删除文件成功,动作有改变,changed=True
else:
result.update({'path': path, 'changed': False, 'state': 'absent'}) # 如果prev_state='absent', 动作没有改变,changed=False, 实现多次操作执行不会有任何改变。 return result def main(): global module module = AnsibleModule(
argument_spec=dict(
state=dict(type='str', choices=['absent', 'directory', 'file', 'hard', 'link', 'touch']),
path=dict(type='path', required=True, aliases=['dest', 'name']),
_original_basename=dict(type='str'), # Internal use only, for recursive ops
recurse=dict(type='bool', default=False),
force=dict(type='bool', default=False), # Note: Should not be in file_common_args in future
follow=dict(type='bool', default=True), # Note: Different default than file_common_args
_diff_peek=dict(type='bool'), # Internal use only, for internal checks in the action plugins
src=dict(type='path'), # Note: Should not be in file_common_args in future
modification_time=dict(type='str'),
modification_time_format=dict(type='str', default='%Y%m%d%H%M.%S'),
access_time=dict(type='str'),
access_time_format=dict(type='str', default='%Y%m%d%H%M.%S'),
),
add_file_common_args=True,
supports_check_mode=True,
) # When we rewrite basic.py, we will do something similar to this on instantiating an AnsibleModule
sys.excepthook = _ansible_excepthook
additional_parameter_handling(module.params)
params = module.params state = params['state']
recurse = params['recurse']
force = params['force']
follow = params['follow']
path = params['path']
src = params['src'] timestamps = {}
timestamps['modification_time'] = keep_backward_compatibility_on_timestamps(params['modification_time'], state)
timestamps['modification_time_format'] = params['modification_time_format']
timestamps['access_time'] = keep_backward_compatibility_on_timestamps(params['access_time'], state)
timestamps['access_time_format'] = params['access_time_format'] # short-circuit for diff_peek
if params['_diff_peek'] is not None:
appears_binary = execute_diff_peek(to_bytes(path, errors='surrogate_or_strict'))
module.exit_json(path=path, changed=False, appears_binary=appears_binary) if state == 'file':
result = ensure_file_attributes(path, follow, timestamps)
elif state == 'directory':
result = ensure_directory(path, follow, recurse, timestamps)
elif state == 'link':
result = ensure_symlink(path, src, follow, force, timestamps)
elif state == 'hard':
result = ensure_hardlink(path, src, follow, force, timestamps)
elif state == 'touch':
result = execute_touch(path, follow, timestamps)
elif state == 'absent':
result = ensure_absent(path) # 执行删除文件时,调用方法 def ensure_absent module.exit_json(**result) if __name__ == '__main__':
main()

[自动化]浅聊ansible的幂等的更多相关文章

  1. 自动化运维 Ansible

    自动化运维 Ansible 特性 (1).no agents:不需要在被管控主机上安装任何客户端: (2).no server:无服务器端,使用时直接运行命令即可: (3).modules in an ...

  2. 浅聊ARP

    今天借用思科公司的Cisco Packet Tracer Student这款软件浅聊ARP 什么是ARP? ARP即地址解析协议(Address Resolution Protocol),是根据Ip地 ...

  3. 自动化运维Ansible安装篇

    Ansible自动化工具之--部署篇 ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优点,实现了 ...

  4. 自动化运维-ansible入门篇

    1.ansible配置 什么是Ansible IT自动化工具 依赖于现有的操作系统凭证来访问控制远程机器 简单易用.安全可靠 Ansible可以完成哪些任务 配置系统 开发软件 编排高级的IT任务 A ...

  5. 运维自动化之1 - ansible 批量主机管理

    2000 - 2016 年,维护的小型机.linux刚开始的2台增加到上千台,手工检查.日常版本升级需要管理太多设备,必须通过运维自动化实现 特别是版本升级,需要到同类机器部署代码.起停设备,必须在一 ...

  6. 服务器/网络/虚拟化/云平台自动化运维-ansible

    ansible与netconf的对比 首先明确一个概念,netconf是协议,ansible是python编写的工具 netconf 使用YANG建模,XML进行数据填充,使用netconf协议进行传 ...

  7. Jenkins+Ansible+Gitlab自动化部署三剑客-Ansible本地搭建

    可以通过git bash连接linux 关闭防火墙,禁用防火墙开机启动,并更爱selinux文件,重启 重新登录并检查禁用 getenforce 安装git yum -y install git ns ...

  8. Python自动化运维ansible从入门到精通

    1. 下载安装 在windows下安装ansible:

  9. 自动化运维—Ansible(上)

    一:为什么选择Ansible 相对于puppet和saltstack,ansible无需客户端,更轻量级 ansible甚至都不用启动服务,仅仅只是一个工具,可以很轻松的实现分布式扩展 更强的远程命令 ...

随机推荐

  1. Solon Web 开发,十二、统一的渲染控制

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  2. 1011day-人口普查系统

    1.Browse.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" ...

  3. Android学习笔记3

    (5)练习做一个实现两个数相乘的APP ①.java代码: //MainActivity.java package com.example.hello; import android.content. ...

  4. 【记录一个问题】go get -u github.com/go-redis/redis出现错误" invalid character '.' after top-level value"

    安装某个库的时候依赖于redis库,总是出现这样的错误: go install go: github.com/go-redis/redis/v7@v7.2.0: parsing go.mod: mis ...

  5. python控制另一台电脑虚拟nao机器人

    nao机器人ip地址 http://doc.aldebaran.com/1-14/software/choregraphe/howto_connect_to_simulated.html 结果 访问另 ...

  6. 云图说|DDS读写两步走,带您领略只读节点的风采

    摘要:为了扩展主节点的读请求能力,DDS提供具备独立连接地址的只读节点,适合独立系统直连访问,以缓解大量读请求给主节点造成的压力. 本文分享自华为云社区<[云图说]第235期 DDS读写两步走 ...

  7. linux判断物理CPU,逻辑CPU和CPU核数

    ① 物理CPU 实际Server中插槽上的CPU个数 物理cpu数量,可以数不重复的 physical id 有几个 ② 逻辑CPU Linux用户对 /proc/cpuinfo 这个文件肯定不陌生. ...

  8. 推荐一个基于Dapr的 Red Dog 的完整微服务应用程序

    微服务尽管构建起来非常困难,但它们已成为一种越来越流行的架构模式.随着开发人员开始将他们现有的单体代码库迁移到微服务系统,他们花费大量时间来处理分布式应用程序带来的固有挑战,例如状态管理和服务调用.通 ...

  9. ApacheCN PythonWeb 译文集 20211028 更新

    Django By Example 中文版 1 创建一个博客应用 2 为博客添加高级功能 3 扩展你的博客应用 4 创建一个社交网站 5 分享内容到你的网站 6 跟踪用户动作 7 构建在线商店 8 管 ...

  10. canvas绘制“飞机大战”小游戏,真香!

    canvas是ArkUI开发框架里的画布组件,常用于自定义绘制图形.因为其轻量.灵活.高效等优点,被广泛应用于UI界面开发中. 本期,我们将为大家介绍canvas组件的使用. 一.canvas介绍 1 ...