1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
| //event系统 event是salt通信的核心,每一个event可以认为是salt的一个执行单元,比job要宽泛,job可以看成一种特殊的event
例如: 写一个脚本用于监听master的event * 编写脚本: [root@saltserver ~]# vim eventlisten.py #-*- coding:utf-8 -*- """ This script is a generic tool to test event output """
# import python libs from __future__ import absolute_import,print_function import optparse import pprint import time import os
# import salt libs import salt.utils.event
# import 3rd-party libs import salt.ext.six as six
def parse(): """ Parse the script command line inputs """ parser = optparse.OptionParser() parser.add_option( '-s', '--sock-dir', dest='sock_dir', default='/var/run/salt', help=('statically define the directory holding the salt unix sockets for communication') ) parser.add_option( '-n', '--node', dest='node', default='master', help=('state if this listener will attach to a master or a minion daemon,pass "master" or "minion"') ) parser.add_option( '-f', '--func_count', default='', help=('Return a count of the number of minions which hava replied to a job with a ggiven func.') ) parser.add_option( '-i', '--id', default='', help=('if connection to a live master or minion,pass in the id') ) parser.add_option( '-t', '--transport', default='zeromq', help=('Transport to use. Default:\'zeromq\'') )
options, args = parser.parse_args()
opts = {}
for k,v in six.iteritems(options.__dict__): if v is not None: opts[k] = v
opts['sock_dir'] = os.path.join(opts['sock_dir'],opts['node'])
if 'minion' in options.node: if args: opts['id'] = args[0] return opts if options.id: opts['id'] = options.id else: opts['id'] = options.node return opts
def check_access_and_print_warning(sock_dir): """ check if this user is able to access the socket directory and print a warning if not """ if (os.access(sock_dir,os.R_OK) and os.access(sock_dir,os.W_OK) and os.access(sock_dir,os.X_OK)): return else: print('Warning: Events will not be reported "(not able to access {0})".format(sock_dir)')
def listen(opts): """ attach to the pub socket and grab messges """ event = salt.utils.event.get_event( opts['node'], sock_dir = opts['sock_dir'], transport = opts['transport'], opts = opts, listen = True ) check_access_and_print_warning(opts['sock_dir']) print(event.puburi) jid_counter = 0 found_minions = [] while True: ret = event.get_event(full=True) if ret is None: continue if opts['func_count']: data = ret.get('data',False) if data: if 'id' in six.iterkeys(data) and data.get('id',False) not in found_minions: if data['fun'] == opts['func_count']: jid_counter += 1 found_minions.append(data['id']) print('Reply received from [{0}]. Total replies now:[{1}].'.format(ret['data']['id'],jid_counter)) continue else: print('Event fired at {0}'.format(time.asctime())) print('*' * 25) print('Tag: {0}'.format(ret['tag'])) print('Data:') pprint.pprint(ret['data'])
if __name__ == '__main__': opts = parse() listen(opts)
* 在salt-master上执行脚本: [root@saltserver ~]# python eventlisten.py /var/run/salt/master/master_event_pub.ipc
* 在打开一个salt-master终端进行执行: [root@saltserver ~]# salt '*' test.ping 192.168.13.187: True
* 在salt-master上查看输出信息: [root@saltserver ~]# python eventlisten.py /var/run/salt/master/master_event_pub.ipc Event fired at Tue Aug 8 10:06:47 2017 ************************* Tag: 20170808100647714897 Data: {'_stamp': '2017-08-08T02:06:47.715514', 'minions': ['192.168.13.187']} Event fired at Tue Aug 8 10:06:47 2017 ************************* Tag: salt/job/20170808100647714897/new Data: {'_stamp': '2017-08-08T02:06:47.716171', 'arg': [], 'fun': 'test.ping', 'jid': '20170808100647714897', 'minions': ['192.168.13.187'], 'tgt': '*', 'tgt_type': 'glob', 'user': 'root'} Event fired at Tue Aug 8 10:06:47 2017 ************************* Tag: salt/job/20170808100647714897/ret/192.168.13.187 Data: {'_stamp': '2017-08-08T02:06:47.797479', 'cmd': '_return', 'fun': 'test.ping', 'fun_args': [], 'id': '192.168.13.187', 'jid': '20170808100647714897', 'retcode': 0, 'return': True, 'success': True}
综上,event输出包含两部分: 部分一: tag,类似于一个url salt/job/20170808100647714897/new 这条tag从左到右说明了:类型,任务ID,任务标识 部分二: 数据字典,包含:时间戳,调用函数,jid,minion信息
//salt为我们提供了event.send模块可自定义event,例如: * 在master端执行 [root@saltserver ~]# python eventlisten.py /var/run/salt/master/master_event_pub.ipc * 在minion端执行 [root@saltminion ~]# salt-call event.send myco/mytag foo=Foo bar=Bar local: True * 在master端查看 [root@saltserver ~]# python eventlisten.py /var/run/salt/master/master_event_pub.ipc Event fired at Tue Aug 8 10:21:41 2017 ************************* Tag: salt/auth Data: {'_stamp': '2017-08-08T02:21:41.187922', 'act': 'accept', 'id': '192.168.13.187', 'pub': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnZHnTfGzMpKiNqPmwM1Q\nrgnRGSrA8eNghWRBECq+raT3qG99xvY7sjP1at8Ul/fnEMCC/K1W4CJz/6TN2lG/\n1jVh77zk9W/PbABGv5i00ZpmxZBtgNywRj4wL9IPPDmalSqm13HnjnVQ7+1I4MK7\naQDmkihGWynSh5U/CGLpApWNowcGw2Xui0d3jdrhGjngvmFuwooCLHlXDOXE3kLY\n1/5oE1+NpM4+6Hbg09XQ6wXtAnM7zNW1GFBfuNTh9ZymkicUso8uqZXCH2dUrf+e\n8VViFb01jBOBgThXm4hmqyF+NfbrjlFmcfSMJ73pJBC1VvmfQ4+F9oSksJGVufkl\n7QIDAQAB\n-----END PUBLIC KEY-----', 'result': True} Event fired at Tue Aug 8 10:21:41 2017 ************************* Tag: minion/refresh/192.168.13.187 Data: {'Minion data cache refresh': '192.168.13.187', '_stamp': '2017-08-08T02:21:41.311715'} Event fired at Tue Aug 8 10:21:41 2017 ************************* Tag: myco/mytag Data: {'_stamp': '2017-08-08T02:21:41.396306', 'cmd': '_minion_event', 'data': {'__pub_fun': 'event.send', '__pub_jid': '20170808102141379062', '__pub_pid': 31706, '__pub_tgt': 'salt-call', 'bar': 'Bar', 'foo': 'Foo'}, 'id': '192.168.13.187', 'tag': 'myco/mytag'} Event fired at Tue Aug 8 10:21:41 2017 ************************* Tag: salt/job/20170808102141404168/ret/192.168.13.187 Data: {'_stamp': '2017-08-08T02:21:41.405667', 'arg': ['myco/mytag', 'foo=Foo', 'bar=Bar'], 'cmd': '_return', 'fun': 'event.send', 'fun_args': ['myco/mytag', 'foo=Foo', 'bar=Bar'], 'id': '192.168.13.187', 'jid': '20170808102141404168', 'retcode': 0, 'return': True, 'tgt': '192.168.13.187', 'tgt_type': 'glob'}
综上,我们看到新产生的event的tag正是我们自己触发的Event.我们既然可以获取这么多的Event,如果能对这些event做定制化的相应会使salt更加灵活强大. salt为我们设计了Reactor系统,可以对event做出相应
//reactor系统 reactor分两部分来配置: 部分一: 在master配置文件中,定义哪些event触发哪些reactor文件 部分二: reactor的SLS配置文件,定义对事件作出相应时采取哪些操作
例如:(修改master配置) * 修改master配置文件 [root@saltserver ~]# vim /etc/salt/master reactor: - 'myco/*': - salt://reactor.sls
* 重启salt-master [root@saltserver ~]# pkill salt-master [root@saltserver ~]# salt-master -c /etc/salt -d
* 定义reactor.sls文件 [root@saltserver ~]# vim /srv/salt/reactor.sls my_first_reactor: local.cmd.run: - tgt: '192.168.13.187' - arg: - 'touch /tmp/my_first_reactor'
* 在master上执行 [root@saltserver ~]# python eventlisten.py /var/run/salt/master/master_event_pub.ipc
* 在minion上执行 [root@saltminion ~]# salt-call event.send myco/mytag foo=Foo bar=Bar local: True
* 在master上观察输出结果 [root@saltserver ~]# python eventlisten.py /var/run/salt/master/master_event_pub.ipc Event fired at Tue Aug 8 10:32:51 2017 ************************* Tag: salt/auth Data: {'_stamp': '2017-08-08T02:32:51.543849', 'act': 'accept', 'id': '192.168.13.187', 'pub': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnZHnTfGzMpKiNqPmwM1Q\nrgnRGSrA8eNghWRBECq+raT3qG99xvY7sjP1at8Ul/fnEMCC/K1W4CJz/6TN2lG/\n1jVh77zk9W/PbABGv5i00ZpmxZBtgNywRj4wL9IPPDmalSqm13HnjnVQ7+1I4MK7\naQDmkihGWynSh5U/CGLpApWNowcGw2Xui0d3jdrhGjngvmFuwooCLHlXDOXE3kLY\n1/5oE1+NpM4+6Hbg09XQ6wXtAnM7zNW1GFBfuNTh9ZymkicUso8uqZXCH2dUrf+e\n8VViFb01jBOBgThXm4hmqyF+NfbrjlFmcfSMJ73pJBC1VvmfQ4+F9oSksJGVufkl\n7QIDAQAB\n-----END PUBLIC KEY-----', 'result': True} Event fired at Tue Aug 8 10:32:51 2017 ************************* Tag: minion/refresh/192.168.13.187 Data: {'Minion data cache refresh': '192.168.13.187', '_stamp': '2017-08-08T02:32:51.669152'} Event fired at Tue Aug 8 10:32:51 2017 ************************* Tag: myco/mytag Data: {'_stamp': '2017-08-08T02:32:51.755789', 'cmd': '_minion_event', 'data': {'__pub_fun': 'event.send', '__pub_jid': '20170808103251736557', '__pub_pid': 31742, '__pub_tgt': 'salt-call', 'bar': 'Bar', 'foo': 'Foo'}, 'id': '192.168.13.187', 'tag': 'myco/mytag'} Event fired at Tue Aug 8 10:32:51 2017 ************************* Tag: salt/job/20170808103251765140/ret/192.168.13.187 Data: {'_stamp': '2017-08-08T02:32:51.768086', 'arg': ['myco/mytag', 'foo=Foo', 'bar=Bar'], 'cmd': '_return', 'fun': 'event.send', 'fun_args': ['myco/mytag', 'foo=Foo', 'bar=Bar'], 'id': '192.168.13.187', 'jid': '20170808103251765140', 'retcode': 0, 'return': True, 'tgt': '192.168.13.187', 'tgt_type': 'glob'} Event fired at Tue Aug 8 10:32:51 2017 ************************* Tag: 20170808103251827538 Data: {'_stamp': '2017-08-08T02:32:51.829254', 'minions': ['192.168.13.187']} Event fired at Tue Aug 8 10:32:51 2017 ************************* Tag: salt/job/20170808103251827538/new Data: {'_stamp': '2017-08-08T02:32:51.829749', 'arg': ['touch /tmp/my_first_reactor'], 'fun': 'cmd.run', 'jid': '20170808103251827538', 'minions': ['192.168.13.187'], 'tgt': '192.168.13.187', 'tgt_type': 'glob', 'user': 'root'} Event fired at Tue Aug 8 10:32:51 2017 ************************* Tag: salt/auth Data: {'_stamp': '2017-08-08T02:32:51.890407', 'act': 'accept', 'id': '192.168.13.187', 'pub': '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnZHnTfGzMpKiNqPmwM1Q\nrgnRGSrA8eNghWRBECq+raT3qG99xvY7sjP1at8Ul/fnEMCC/K1W4CJz/6TN2lG/\n1jVh77zk9W/PbABGv5i00ZpmxZBtgNywRj4wL9IPPDmalSqm13HnjnVQ7+1I4MK7\naQDmkihGWynSh5U/CGLpApWNowcGw2Xui0d3jdrhGjngvmFuwooCLHlXDOXE3kLY\n1/5oE1+NpM4+6Hbg09XQ6wXtAnM7zNW1GFBfuNTh9ZymkicUso8uqZXCH2dUrf+e\n8VViFb01jBOBgThXm4hmqyF+NfbrjlFmcfSMJ73pJBC1VvmfQ4+F9oSksJGVufkl\n7QIDAQAB\n-----END PUBLIC KEY-----', 'result': True} Event fired at Tue Aug 8 10:32:51 2017 ************************* Tag: salt/job/20170808103251827538/ret/192.168.13.187 Data: {'_stamp': '2017-08-08T02:32:51.984504', 'cmd': '_return', 'fun': 'cmd.run', 'fun_args': ['touch /tmp/my_first_reactor'], 'id': '192.168.13.187', 'jid': '20170808103251827538', 'retcode': 0, 'return': '', 'success': True}
* 在minion上查看 [root@saltminion ~]# ls -1 /tmp/my_first_reactor /tmp/my_first_reactor
|