|
|
@ -15,7 +15,7 @@ from threading import Thread
|
|
|
|
import os
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import subprocess
|
|
|
|
from monitor import ProcessCounter
|
|
|
|
from monitor import ProcessCounter
|
|
|
|
from utils.transport import QueueListener, QueueWriter
|
|
|
|
from utils.transport import QueueListener, QueueWriter, QueueReader
|
|
|
|
class Actor:
|
|
|
|
class Actor:
|
|
|
|
def __init__(self,config):
|
|
|
|
def __init__(self,config):
|
|
|
|
self.config = config
|
|
|
|
self.config = config
|
|
|
@ -56,6 +56,7 @@ class Actor:
|
|
|
|
|
|
|
|
|
|
|
|
class Kill(Actor):
|
|
|
|
class Kill(Actor):
|
|
|
|
def isValid(self,item):
|
|
|
|
def isValid(self,item):
|
|
|
|
|
|
|
|
print self.config
|
|
|
|
return (item is not None) and (item in self.config)
|
|
|
|
return (item is not None) and (item in self.config)
|
|
|
|
def process(self,item):
|
|
|
|
def process(self,item):
|
|
|
|
cmd = "".join(["ps -eo pid,command|grep ",item,'|grep -E "^ {0,1}[0-9]+" -o|xargs kill -9'])
|
|
|
|
cmd = "".join(["ps -eo pid,command|grep ",item,'|grep -E "^ {0,1}[0-9]+" -o|xargs kill -9'])
|
|
|
@ -67,7 +68,7 @@ class Start(Actor):
|
|
|
|
def __init__(self,config):
|
|
|
|
def __init__(self,config):
|
|
|
|
Actor.__init__(self,config)
|
|
|
|
Actor.__init__(self,config)
|
|
|
|
def isValid(self,name):
|
|
|
|
def isValid(self,name):
|
|
|
|
return name in self.config:
|
|
|
|
return name in self.config
|
|
|
|
|
|
|
|
|
|
|
|
def process(self,name):
|
|
|
|
def process(self,name):
|
|
|
|
item = self.config[name]
|
|
|
|
item = self.config[name]
|
|
|
@ -87,43 +88,87 @@ class Orchestrator(Actor,Thread):
|
|
|
|
Thread.__init__(self)
|
|
|
|
Thread.__init__(self)
|
|
|
|
Actor.__init__(self,config)
|
|
|
|
Actor.__init__(self,config)
|
|
|
|
self.actors = {}
|
|
|
|
self.actors = {}
|
|
|
|
for id in config['actions'] :
|
|
|
|
self.is_master_node = False
|
|
|
|
conf = config['actions'][id]
|
|
|
|
self.items = []
|
|
|
|
item = eval("".join([id,"(",json.dumps(conf),")"]))
|
|
|
|
#
|
|
|
|
|
|
|
|
# If the configuration only has id,key then this is NOT the maestro
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
host = config['api']
|
|
|
|
|
|
|
|
qid = config['id']
|
|
|
|
|
|
|
|
if 'actions' in config :
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# We are to assume this is the maestro/main node, and it will make the configuration available to other nodes
|
|
|
|
|
|
|
|
# NOTE: This is has a predefined master thus is subject to known short comings (zombies)
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
q = QueueWriter(host=host,uid=config['key'],qid=qid)
|
|
|
|
|
|
|
|
q.flush(config['id'])
|
|
|
|
|
|
|
|
q.write(label=qid,row=json.dumps(config['actions']))
|
|
|
|
|
|
|
|
q.close()
|
|
|
|
|
|
|
|
self.is_master_node = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
qid = config['master']
|
|
|
|
|
|
|
|
q = QueueReader(host=host,uid=config['key'],qid=qid)
|
|
|
|
|
|
|
|
r = q.read()
|
|
|
|
|
|
|
|
q.close()
|
|
|
|
|
|
|
|
info = r[qid][0]
|
|
|
|
|
|
|
|
self.init(info)
|
|
|
|
|
|
|
|
print "Initialized ***** ",self.getIdentifier(), " as ",config['id']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# This object will have to request for the configuration
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
#for id in config['actions'] :
|
|
|
|
|
|
|
|
#conf = config['actions'][id]
|
|
|
|
|
|
|
|
#item = eval("".join([id,"(",json.dumps(conf),")"]))
|
|
|
|
|
|
|
|
#self.actors[id.lower()] = item
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
This function is designed to provide the orchestrator a configuration
|
|
|
|
|
|
|
|
@pre
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
def init(self,config):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for id in config:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setup_info = config[id]
|
|
|
|
|
|
|
|
item = eval("".join([id,"(",json.dumps(setup_info),")"]))
|
|
|
|
self.actors[id.lower()] = item
|
|
|
|
self.actors[id.lower()] = item
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def callback(self,channel,method,header,stream):
|
|
|
|
def callback(self,channel,method,header,stream):
|
|
|
|
|
|
|
|
|
|
|
|
message = json.loads(stream)
|
|
|
|
message = json.loads(stream)
|
|
|
|
content = message['content']
|
|
|
|
if 'content' in message :
|
|
|
|
sender = message['from']
|
|
|
|
content = message['content']
|
|
|
|
to = message['to']
|
|
|
|
sender = message['from']
|
|
|
|
if content.lower() == 'quit' or to == 'quit':
|
|
|
|
to = message['to']
|
|
|
|
channel.close()
|
|
|
|
if content.lower() == 'quit' or to == 'quit':
|
|
|
|
print " *** ",self.getIdentifier()
|
|
|
|
channel.close()
|
|
|
|
elif content.lower() == 'ping' or to == 'ping':
|
|
|
|
|
|
|
|
self.post(to=sender,content="1")
|
|
|
|
elif content.lower() == 'ping' or to == 'ping':
|
|
|
|
else:
|
|
|
|
self.post(to=sender,content="1")
|
|
|
|
id = to.lower()
|
|
|
|
|
|
|
|
actor = self.actors[id]
|
|
|
|
|
|
|
|
if actor.isValid(content) :
|
|
|
|
|
|
|
|
actor.process(content)
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
content = {"status":"invalid","content":content}
|
|
|
|
id = to.lower()
|
|
|
|
|
|
|
|
actor = self.actors[id]
|
|
|
|
self.post(to=sender,content=content)
|
|
|
|
print "\tPerforming ",actor.getIdentifier()," on ",content," status ",actor.isValid(content)
|
|
|
|
|
|
|
|
if actor.isValid(content) :
|
|
|
|
|
|
|
|
actor.process(content)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
content = {"status":"invalid","content":content}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.post(to=sender,content=content)
|
|
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
def run(self):
|
|
|
|
info = {}
|
|
|
|
info = {}
|
|
|
|
host = self.config['api']
|
|
|
|
host = self.config['api']
|
|
|
|
uid = self.config['key']
|
|
|
|
uid = self.config['key']
|
|
|
|
qid = self.config['id']
|
|
|
|
qid = self.config['id']
|
|
|
|
|
|
|
|
if not self.is_master_node :
|
|
|
|
qlistener = QueueListener(qid=qid,uid=uid,host=host)
|
|
|
|
qlistener = QueueListener(qid=qid,uid=uid,host=host)
|
|
|
|
qlistener.callback = self.callback
|
|
|
|
qlistener.callback = self.callback
|
|
|
|
qlistener.read()
|
|
|
|
qlistener.read()
|
|
|
|
#r = [self.process(item) for item in self.items]
|
|
|
|
r = [self.process(item) for item in self.items]
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
This class is designed to send a message to a given AMQP enpoint
|
|
|
|
This class is designed to send a message to a given AMQP enpoint
|
|
|
@ -144,8 +189,19 @@ config = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#thread = Orchestrator(config)
|
|
|
|
|
|
|
|
#thread.start()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config = {
|
|
|
|
|
|
|
|
"master":"demo-000",
|
|
|
|
|
|
|
|
"id":"demo-001",
|
|
|
|
|
|
|
|
"key":"[0v8]-247&7!v3","api":"localhost"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
thread = Orchestrator(config)
|
|
|
|
thread = Orchestrator(config)
|
|
|
|
thread.start()
|
|
|
|
thread.start()
|
|
|
|
|
|
|
|
|
|
|
|
#config = {"id":"demo","key":"[0v8]-247&7!v3","api":"localhost"}
|
|
|
|
#config = {"id":"demo","key":"[0v8]-247&7!v3","api":"localhost"}
|
|
|
|
#actor = Kill(config)
|
|
|
|
#actor = Kill(config)
|
|
|
|
#actor.start()
|
|
|
|
#actor.start()
|
|
|
|