diff --git a/daemon/core/misc/xmlutils.py b/daemon/core/misc/xmlutils.py index 69d7d1c8..54543c14 100644 --- a/daemon/core/misc/xmlutils.py +++ b/daemon/core/misc/xmlutils.py @@ -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. diff --git a/daemon/core/session.py b/daemon/core/session.py index 6ee6f221..9a8d990a 100644 --- a/daemon/core/session.py +++ b/daemon/core/session.py @@ -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 diff --git a/daemon/sbin/core-daemon b/daemon/sbin/core-daemon index 98611dd4..10b457b0 100755 --- a/daemon/sbin/core-daemon +++ b/daemon/sbin/core-daemon @@ -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)