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
|
return None
|
||||||
|
|
||||||
class CoreDocumentParser(object):
|
class CoreDocumentParser(object):
|
||||||
def __init__(self, session, filename):
|
def __init__(self, session, filename, start=False):
|
||||||
self.session = session
|
self.session = session
|
||||||
self.verbose = self.session.getcfgitembool('verbose', False)
|
self.verbose = self.session.getcfgitembool('verbose', False)
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.dom = parse(filename)
|
self.dom = parse(filename)
|
||||||
|
self.start = start
|
||||||
|
|
||||||
#self.scenario = getoneelement(self.dom, "Scenario")
|
#self.scenario = getoneelement(self.dom, "Scenario")
|
||||||
self.np = getoneelement(self.dom, "NetworkPlan")
|
self.np = getoneelement(self.dom, "NetworkPlan")
|
||||||
|
@ -197,7 +198,7 @@ class CoreDocumentParser(object):
|
||||||
(name, type))
|
(name, type))
|
||||||
continue
|
continue
|
||||||
n = self.session.addobj(cls = nodecls, objid = id, name = name,
|
n = self.session.addobj(cls = nodecls, objid = id, name = name,
|
||||||
start = False)
|
start = self.start)
|
||||||
if name in self.coords:
|
if name in self.coords:
|
||||||
x, y, z = self.coords[name]
|
x, y, z = self.coords[name]
|
||||||
n.setposition(x, y, z)
|
n.setposition(x, y, z)
|
||||||
|
@ -227,7 +228,7 @@ class CoreDocumentParser(object):
|
||||||
else:
|
else:
|
||||||
nodecls = pycore.nodes.CoreNode
|
nodecls = pycore.nodes.CoreNode
|
||||||
n = self.session.addobj(cls = nodecls, objid = id, name = name,
|
n = self.session.addobj(cls = nodecls, objid = id, name = name,
|
||||||
start = False)
|
start = self.start)
|
||||||
if name in self.coords:
|
if name in self.coords:
|
||||||
x, y, z = self.coords[name]
|
x, y, z = self.coords[name]
|
||||||
n.setposition(x, y, z)
|
n.setposition(x, y, z)
|
||||||
|
@ -763,10 +764,15 @@ class CoreDocumentWriter(Document):
|
||||||
addtextparamtoparent(self, meta, k, v)
|
addtextparamtoparent(self, meta, k, v)
|
||||||
#addparamtoparent(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.
|
''' 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):
|
def savesessionxml(session, filename):
|
||||||
''' Export a session to the EmulationScript XML format.
|
''' Export a session to the EmulationScript XML format.
|
||||||
|
|
|
@ -221,19 +221,16 @@ class Session(object):
|
||||||
self._time = time.time()
|
self._time = time.time()
|
||||||
self._state = state
|
self._state = state
|
||||||
replies = []
|
replies = []
|
||||||
|
if self.isconnected() and info:
|
||||||
if not self.isconnected():
|
|
||||||
return replies
|
|
||||||
if info:
|
|
||||||
statename = coreapi.state_name(state)
|
statename = coreapi.state_name(state)
|
||||||
self._handlerslock.acquire()
|
with self._handlerslock:
|
||||||
for handler in self._handlers:
|
for handler in self._handlers:
|
||||||
handler.info("SESSION %s STATE %d: %s at %s" % \
|
handler.info("SESSION %s STATE %d: %s at %s" % \
|
||||||
(self.sessionid, state, statename, time.ctime()))
|
(self.sessionid, state, statename,
|
||||||
self._handlerslock.release()
|
time.ctime()))
|
||||||
self.writestate(state)
|
self.writestate(state)
|
||||||
self.runhook(state)
|
self.runhook(state)
|
||||||
if sendevent:
|
if self.isconnected() and sendevent:
|
||||||
tlvdata = ""
|
tlvdata = ""
|
||||||
tlvdata += coreapi.CoreEventTlv.pack(coreapi.CORE_TLV_EVENT_TYPE,
|
tlvdata += coreapi.CoreEventTlv.pack(coreapi.CORE_TLV_EVENT_TYPE,
|
||||||
state)
|
state)
|
||||||
|
@ -587,6 +584,24 @@ class Session(object):
|
||||||
# nodes on slave servers that will be booted and those servers will
|
# nodes on slave servers that will be booted and those servers will
|
||||||
# send a node status response message
|
# send a node status response message
|
||||||
self.checkruntime()
|
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):
|
def checkruntime(self):
|
||||||
''' Check if we have entered the runtime state, that all nodes have been
|
''' 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:
|
if self.getstate() == coreapi.CORE_EVENT_RUNTIME_STATE:
|
||||||
return
|
return
|
||||||
session_node_count = int(self.node_count)
|
session_node_count = int(self.node_count)
|
||||||
nc = 0
|
nc = self.getnodecount()
|
||||||
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
|
|
||||||
# count booted nodes not emulated on this server
|
# count booted nodes not emulated on this server
|
||||||
# TODO: let slave server determine RUNTIME and wait for Event Message
|
# TODO: let slave server determine RUNTIME and wait for Event Message
|
||||||
# broker.getbootocunt() counts all CoreNodes from status reponse
|
# broker.getbootocunt() counts all CoreNodes from status reponse
|
||||||
|
|
|
@ -861,11 +861,9 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
|
||||||
''' Register Message Handler
|
''' Register Message Handler
|
||||||
'''
|
'''
|
||||||
replies = []
|
replies = []
|
||||||
|
# execute a Python script or XML file
|
||||||
# execute a Python script
|
|
||||||
ex = msg.gettlv(coreapi.CORE_TLV_REG_EXECSRV)
|
ex = msg.gettlv(coreapi.CORE_TLV_REG_EXECSRV)
|
||||||
if ex:
|
if ex:
|
||||||
# TODO: load and execute XML files here
|
|
||||||
try:
|
try:
|
||||||
self.info("executing '%s'" % ex)
|
self.info("executing '%s'" % ex)
|
||||||
if isinstance(self.server, CoreUdpServer):
|
if isinstance(self.server, CoreUdpServer):
|
||||||
|
@ -875,12 +873,16 @@ class CoreRequestHandler(SocketServer.BaseRequestHandler):
|
||||||
if msg.flags & coreapi.CORE_API_STR_FLAG:
|
if msg.flags & coreapi.CORE_API_STR_FLAG:
|
||||||
old_session_ids = set(server.getsessionids())
|
old_session_ids = set(server.getsessionids())
|
||||||
sys.argv = shlex.split(ex)
|
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.
|
# TODO: Script may not return; run in separate thread here.
|
||||||
# Wait for some configurable timeout period, then check
|
# Wait for some configurable timeout period, then check
|
||||||
# for new session below. Wait for session to enter
|
# for new session below. Wait for session to enter
|
||||||
# the runtime state, then send back the register message.
|
# 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:
|
if msg.flags & coreapi.CORE_API_STR_FLAG:
|
||||||
new_session_ids = set(server.getsessionids())
|
new_session_ids = set(server.getsessionids())
|
||||||
new_sid = new_session_ids.difference(old_session_ids)
|
new_sid = new_session_ids.difference(old_session_ids)
|
||||||
|
|
Loading…
Reference in a new issue