allow executing XML files from daemon from Register Message

(like a Python script)
added start flag to xmlutils.opensessionxml(), 
XML file will be parsed into a live running session
(Boeing r1792)
This commit is contained in:
ahrenholz 2013-11-25 19:54:02 +00:00
parent 93f96c7707
commit 1e8abc4c1e
3 changed files with 44 additions and 34 deletions

View file

@ -121,11 +121,12 @@ def xmltypetonodeclass(session, type):
return None
class CoreDocumentParser(object):
def __init__(self, session, filename):
def __init__(self, session, filename, start=False):
self.session = session
self.verbose = self.session.getcfgitembool('verbose', False)
self.filename = filename
self.dom = parse(filename)
self.start = start
#self.scenario = getoneelement(self.dom, "Scenario")
self.np = getoneelement(self.dom, "NetworkPlan")
@ -197,7 +198,7 @@ class CoreDocumentParser(object):
(name, type))
continue
n = self.session.addobj(cls = nodecls, objid = id, name = name,
start = False)
start = self.start)
if name in self.coords:
x, y, z = self.coords[name]
n.setposition(x, y, z)
@ -227,7 +228,7 @@ class CoreDocumentParser(object):
else:
nodecls = pycore.nodes.CoreNode
n = self.session.addobj(cls = nodecls, objid = id, name = name,
start = False)
start = self.start)
if name in self.coords:
x, y, z = self.coords[name]
n.setposition(x, y, z)
@ -763,10 +764,15 @@ class CoreDocumentWriter(Document):
addtextparamtoparent(self, meta, k, v)
#addparamtoparent(self, meta, k, v)
def opensessionxml(session, filename):
def opensessionxml(session, filename, start=False):
''' Import a session from the EmulationScript XML format.
'''
doc = CoreDocumentParser(session, filename)
doc = CoreDocumentParser(session, filename, start)
if start:
session.name = os.path.basename(filename)
session.filename = filename
session.node_count = str(session.getnodecount())
session.checkruntime()
def savesessionxml(session, filename):
''' Export a session to the EmulationScript XML format.

View file

@ -221,19 +221,16 @@ class Session(object):
self._time = time.time()
self._state = state
replies = []
if not self.isconnected():
return replies
if info:
if self.isconnected() and info:
statename = coreapi.state_name(state)
self._handlerslock.acquire()
for handler in self._handlers:
handler.info("SESSION %s STATE %d: %s at %s" % \
(self.sessionid, state, statename, time.ctime()))
self._handlerslock.release()
with self._handlerslock:
for handler in self._handlers:
handler.info("SESSION %s STATE %d: %s at %s" % \
(self.sessionid, state, statename,
time.ctime()))
self.writestate(state)
self.runhook(state)
if sendevent:
if self.isconnected() and sendevent:
tlvdata = ""
tlvdata += coreapi.CoreEventTlv.pack(coreapi.CORE_TLV_EVENT_TYPE,
state)
@ -587,6 +584,24 @@ class Session(object):
# nodes on slave servers that will be booted and those servers will
# send a node status response message
self.checkruntime()
def getnodecount(self):
''' Returns the number of CoreNodes and CoreNets, except for those
that are not considered in the GUI's node count.
'''
with self._objslock:
count = len(filter(lambda(x): \
not isinstance(x, (nodes.PtpNet, nodes.CtrlNet)),
self.objs()))
# on Linux, GreTapBridges are auto-created, not part of
# GUI's node count
if 'GreTapBridge' in globals():
count -= len(filter(lambda(x): \
isinstance(x, GreTapBridge) and not \
isinstance(x, nodes.TunnelNode),
self.objs()))
return count
def checkruntime(self):
''' Check if we have entered the runtime state, that all nodes have been
@ -601,20 +616,7 @@ class Session(object):
if self.getstate() == coreapi.CORE_EVENT_RUNTIME_STATE:
return
session_node_count = int(self.node_count)
nc = 0
with self._objslock:
for obj in self.objs():
# these networks may be added by the daemon and are not
# considered in the GUI's node count
if isinstance(obj, (nodes.PtpNet, nodes.CtrlNet)):
continue
# on Linux, GreTapBridges are auto-created, not part of GUI's
# node count
if 'GreTapBridge' in globals():
if isinstance(obj, GreTapBridge) and \
not isinstance(obj, nodes.TunnelNode):
continue
nc += 1
nc = self.getnodecount()
# count booted nodes not emulated on this server
# TODO: let slave server determine RUNTIME and wait for Event Message
# broker.getbootocunt() counts all CoreNodes from status reponse

View file

@ -861,11 +861,9 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
''' Register Message Handler
'''
replies = []
# execute a Python script
# execute a Python script or XML file
ex = msg.gettlv(coreapi.CORE_TLV_REG_EXECSRV)
if ex:
# TODO: load and execute XML files here
try:
self.info("executing '%s'" % ex)
if isinstance(self.server, CoreUdpServer):
@ -875,12 +873,16 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
if msg.flags & coreapi.CORE_API_STR_FLAG:
old_session_ids = set(server.getsessionids())
sys.argv = shlex.split(ex)
scriptname = sys.argv[0]
filename = sys.argv[0]
if os.path.splitext(filename)[1].lower() == '.xml':
session = server.getsession(useexisting=False)
opensessionxml(session, filename, start=True)
# TODO: Script may not return; run in separate thread here.
# Wait for some configurable timeout period, then check
# for new session below. Wait for session to enter
# the runtime state, then send back the register message.
execfile(scriptname, {'server': server})
else:
execfile(filename, {'server': server})
if msg.flags & coreapi.CORE_API_STR_FLAG:
new_session_ids = set(server.getsessionids())
new_sid = new_session_ids.difference(old_session_ids)