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. Codeforces Round #475 Div. 2 A B C D

    A - Splits 题意 将一个正整数拆分成若干个正整数的和,从大到小排下来,与第一个数字相同的数字的个数为这个拆分的权重. 问\(n\)的所有拆分的不同权重可能个数. 思路 全拆成1,然后每次将2 ...

  2. python中的with与上下文管理器

    #转载请留言联系 很多人平时需要打开文件进行读取写入操作时,通常这样: f = open('文件路径','w') f.write(data) f.close 这样写有一个潜在的问题,如果在调用 wri ...

  3. 执行监听器( Execution listener)

    相关类: org.activiti.engine.delegate.ExecutionListener org.activiti.engine.delegate.TaskListener org.ac ...

  4. 关于 log4j.additivity的说明

    log4j.additivity是 子Logger 是否继承 父Logger 的 输出源(appender) 的标志位.具体说,默认情况下 子Logger 会继承 父Logger 的appender, ...

  5. Eclipse,myeclipse安装 配置Maven

    本文转自http://www.cnblogs.com/timeng/archive/2013/05/07/maven_install.html myeclipse自带了maven插件,但是和原生插件还 ...

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

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

  7. Go简单的Goroutine示例

    最简单的,接下来,会是竞争,加锁... package main import ( "fmt" "runtime" "sync" ) var ...

  8. 使用httpclient异步调用WebAPI接口

    最近的工作需要使用Bot Framework调用原有的WebAPI查询数据,查找了一些方法,大部分都是使用HttpClient调用的,现时贴出代码供参考 using System; using Sys ...

  9. 基于tinkphp3.2获取openid

    <?php namespace Home\Controller; use Think\Controller; /** * 基础 */ class BaseController extends C ...

  10. PHP实现支付宝即时到账功能

    本文实例为大家分享了PHP支付宝即时到账功能的实现代码,供大家参考,具体内容如下 首先需要下载即时到账交易接口,传送门https://doc.open.alipay.com/doc2/detail?t ...