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:
parent
93f96c7707
commit
1e8abc4c1e
3 changed files with 44 additions and 34 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue