saltstack的master上minion连接较多,下面这个程序可以分析哪些minion任务执行成功,哪些执行失败以及哪些没有返回。

脚本说明:

一、最先打印出本次任务的job id、command name以及其它相关信息,然后是本次任务的执行流程和结果,这和我们单独执行这个命令是一致的。最后程序会打印出所有未成功的任务和未返回的任务,并且重新执行一遍。 这里要说明的是,因为没有查看对应的情景,对于失败任务的排判断做的不好,另外minion未连接我也归为任务未返回,并且会再执行一遍,实际上如果是minion未连接,则不应该执行。

二、 程序我们先派生子进程去执行salt命令,再salt命令执行完毕后,我们的程序会对其中失败的和未返回的minion任务二次执行

三、编写脚本

import salt.utils.event
import re
import signal, time
import sys
import os
def single_handler(target):
os.execl('/usr/bin/salt', 'salt', target, 'state.sls', 'os') def handler(num1, num2):
#signal.signal(signal.SIGCLD,signal.SIG_IGN)
print 'We are in signal handler'
print 'Job Not Ret: '+str(record[jid])
print ' Job Failed: '+str(failedrecord[jid])
print 'all done...'
for item in failedrecord[jid]:
#print item
try:
pid = os.fork()
if pid == 0:
single_handler(item)
except OSError:
print 'we exec. '+ item +' error!'
for item in record[jid]:
#print item
try:
print 'fork ok ' + item
pid = os.fork()
if pid == 0 :
single_handler(item)
except OSError:
print 'we exec. '+item + ' error!'
sys.stdout.flush()
os._exit(0) fd = open('/tmp/record', 'w+')
#sys.stdout = fd
#sys.stderr = fd signal.signal(signal.SIGCLD, handler) #fd = open('/var/log/record', 'w+')
os.dup2(fd.fileno(), sys.stdout.fileno())
os.dup2(fd.fileno(), sys.stderr.fileno()) #sys.stdout = fd
#sys.stderr = fd try:
pid = os.fork()
if pid == 0:
time.sleep(2)
try:
os.execl('/usr/bin/salt', 'salt', '*', 'state.sls', 'os')
except OSError:
print 'exec error!'
os._exit(1)
except OSError:
print 'first fork error!'
os._exit(1)
event = salt.utils.event.MasterEvent('/var/run/salt/master')
flag=False
reg=re.compile('salt/job/([0-9]+)/new')
reg1=reg
#a process to exec. command, but will sleep some time
#another process listen the event
#if we use this method, we can filter the event through func. name
record={}
failedrecord={}
jid = 0 #try:
for eachevent in event.iter_events(tag='salt/job',full=True):
eachevent=dict(eachevent)
result = reg.findall(eachevent['tag'])
if not flag and result:
flag = True
jid = result[0]
print " job_id: " + jid
print " Command: " + dict(eachevent['data'])['fun'] + ' ' + str(dict(eachevent['data'])['arg'])
print " RunAs: " + dict(eachevent['data'])['user']
print "exec_time: " + dict(eachevent['data'])['_stamp']
print "host_list: " + str(dict(eachevent['data'])['minions'])
sys.stdout.flush()
record[jid]=eachevent['data']['minions']
failedrecord[jid]=[]
reg1 = re.compile('salt/job/'+jid+'/ret/([0-9.]+)')
else:
result = reg1.findall(eachevent['tag'])
if result:
record[jid].remove(result[0])
if not dict(eachevent['data'])['success']:
failedrecord[jid].append(result[0])
#except:
# print 'we in except'
"""
print 'Job Not Ret: '+str(record[jid])
print ' Job Failed: '+str(failedrecord[jid])
for item in failedrecord[jid]:
os.system('salt '+ str(item) + ' state.sls os')
for item in record[jid]:
os.system('salt '+ str(item) + ' state.sls os')
os._exit(0)
"""

执行结果:

   job_id: 20151208025319005896
Command: state.sls ['os']
RunAs: root
exec_time: 2015-12-08T02:53:19.006284
host_list: ['172.18.1.212', '172.18.1.214', '172.18.1.213', '172.18.1.211']
172.18.1.213:
----------
ID: configfilecopy
Function: file.managed
Name: /root/node3
Result: True
Comment: File /root/node3 is in the correct state
Started: 02:53:19.314015
Duration: 13.033 ms
Changes:
----------
ID: commonfile
Function: file.managed
Name: /root/commonfile
Result: True
Comment: File /root/commonfile is in the correct state
Started: 02:53:19.327173
Duration: 1.993 ms
Changes: Summary
------------
Succeeded: 2
Failed: 0
------------
Total states run: 2
172.18.1.212:
----------
ID: configfilecopy
Function: file.managed
Name: /root/node2
Result: True
Comment: File /root/node2 is in the correct state
Started: 02:53:19.337325
Duration: 8.327 ms
Changes:
----------
ID: commonfile
Function: file.managed
Name: /root/commonfile
Result: True
Comment: File /root/commonfile is in the correct state
Started: 02:53:19.345787
Duration: 1.996 ms
Changes: Summary
------------
Succeeded: 2
Failed: 0
------------
Total states run: 2
172.18.1.211:
----------
ID: configfilecopy
Function: file.managed
Name: /root/node1
Result: True
Comment: File /root/node1 is in the correct state
Started: 02:53:19.345017
Duration: 12.741 ms
Changes:
----------
ID: commonfile
Function: file.managed
Name: /root/commonfile
Result: True
Comment: File /root/commonfile is in the correct state
Started: 02:53:19.357873
Duration: 1.948 ms
Changes: Summary
------------
Succeeded: 2
Failed: 0
------------
Total states run: 2
172.18.1.214:
Minion did not return. [Not connected]
We are in signal handler
Job Not Ret: ['172.18.1.214']
Job Failed: []
all done...
fork ok 172.18.1.214
172.18.1.214:
Minion did not return. [Not connected]

利用saltstack的event实现自己的功能的更多相关文章

  1. Python中利用函数装饰器实现备忘功能

    Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下   " ...

  2. ASP.net(C#)利用SQL Server实现注册和登陆功能

    说说我现在吧,楼主现在从事的事IT行业,主攻DotNet技术:当然这次上博客园我也是有备而来,所有再次奉献鄙人拙作,以飨诸位,望诸位不吝赐教. 世界上大多数的工作都是熟练性的工种,编程也不例外,做久了 ...

  3. 利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版)

    利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版) CREATE DEFINER=`root`@`%` FUNCTION `uc_session_login`( `reqjson` JS ...

  4. 利用 Android 系统原生 API 实现分享功能

    利用 Android 系统原生 API 实现分享功能 这篇文章提供一个封装好的 Share2 库供大家参考. GitHub 项目地址:Share2 大家知道,要调用 Android 系统内建的分享功能 ...

  5. 利用SharedPreferences完成记住账号密码的功能

    利用SharedPreferences完成记住账号密码的功能 效果图: 记住密码后,再次登录就会出现账号密码,否则没有. 分析: SharedPreferences可将数据存储到本地的配置文件中 Sh ...

  6. c# wpf 利用截屏键实现截屏功能

    原文:c# wpf 利用截屏键实现截屏功能     最近做一个wpf程序需要截图功能,查找资料费了一些曲折,跟大家分享一下.     先是找到了这样一份代码:     static class Scr ...

  7. 痞子衡嵌入式:一次利用IAR自带CRC完整性校验功能的实践(为KBOOT加BCA)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是利用IAR自带CRC完整性校验功能的一次实践(为KBOOT加BCA). 痞子衡之前写过两篇关于IAR中自带CRC校验功能的文章 < ...

  8. 如何利用ETW(Event Tracing for Windows)记录日志

    ETW是Event Tracing for Windows的简称,它是Windows提供的原生的事件跟踪日志系统.由于采用内核(Kernel)层面的缓冲和日志记录机制,所以ETW提供了一种非常高效的事 ...

  9. [AIR] 利用SnapShot.exe实现QQ截屏功能

    主类(可作文档类): package { import flash.display.Bitmap; import flash.display.Sprite; import flash.events.E ...

随机推荐

  1. bzoj 2820 mobius反演

    学了一晚上mobius,终于A了一道了.... 假设枚举到i,质数枚举到p(程序里的prime[j]),要更新A=i*p的信息. 1. p|i    这时A的素数分解式中,p这一项的次数>=2. ...

  2. Android源码的BUG

    在Android系统移植过程中,遇到很多源码上的BUG.但是我们看到市面上都是没有这些问题的.难道这些BUG在每个开发商都要经历一次解BUG的过程吗?Android释放的源码是否是最新的?暂时没有想法 ...

  3. SpringMVC与Spring的父子容器关系

    问题: 在整合框架的时候有人也许会产生一个问题:能不能只配置一个扫描包加载实现类的扫描驱动,即在根目录下扫描所有的注解(@Controller.@Service.@Repository.@Compne ...

  4. CentOS6.x 安装升级Python2.7.x Python3.4.x

    CentOS6.x 安装升级Python2.7.x Python3.4.x 2015-06-07• CentOS.Linux • 评论关闭 CentOS release 6.6 (Final) 安装升 ...

  5. k8s的回滚应用

    kubectl apply 每次更新应用时 Kubernetes 都会记录下当前的配置,保存为一个 revision(版次),这样就可以回滚到某个特定 revision. 默认配置下,Kubernet ...

  6. VS2010编写C++程序出现error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "StdAfx.h"”?

    用VS2010编写C++程序,编译时出现如下错误: 修改方法: 右击项目,选择属性 点击确定,重新编译,错误解决.

  7. 网关协议:CGI、FastCGI、WSGI

    CGI就像是一座桥,把网页和WEB服务器中的执行程序连接起来,它把HTML接收的指令传递给服务器的执行程序,再把服务器执行程序的结果返还给HTML页. CGI CGI即通用网关接口(Common Ga ...

  8. IOC(控制反转)的理解

    1.IOC的理论背景 我们知道在面向对象设计的软件系统中,它的底层都是由N个对象构成的,各个对象之间通过相互合作,最终实现系统地业务逻辑[1]. 图1 软件系统中耦合的对象 如果我们打开机械式手表的后 ...

  9. C#在 64位系统下出现 “未能加载文件或程序集”错误

    64位系统下,Build的时候,如果选择Any CPU,默认会按照64位进行编译,便无法加载某些旧的dll,这些dll可能是特定到X86 CPU的. 所以,把编译选项中改为 X86CPU,就可以运行了 ...

  10. 自己在用的几个sublime text3插件

    Arduino-like IDE ConvertToUTF8 Emmet(前身是zen coding) Keymap Redefiner Package Control PyV8 SideBarEnh ...