2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
20 from nepi.util.timefuncs import stformat, tsformat
22 from xml.dom import minidom
34 if isinstance(s, str):
35 rv = s.decode("latin1")
36 if isinstance(s, datetime.datetime):
38 elif not isinstance(s, unicode):
42 return rv.replace(u'\x00',u'�')
44 def xmldecode(s, cast = str):
45 ret = s.replace(u'�',u'\x00').encode("ascii")
52 if isinstance(value, bool):
54 if isinstance(value, int):
56 if isinstance(value, float):
61 def to_type(type, value):
68 return value == "True"
74 class ECXMLParser(object):
77 doc = minidom.Document()
79 self._ec_to_xml(doc, ec)
82 xml = doc.toprettyxml(indent=" ", encoding="UTF-8")
84 print >>sys.stderr, "Oops: generating XML from %s" % (data,)
89 def _ec_to_xml(self, doc, ec):
90 ecnode = doc.createElement("experiment")
91 ecnode.setAttribute("exp_id", xmlencode(ec.exp_id))
92 ecnode.setAttribute("run_id", xmlencode(ec.run_id))
93 ecnode.setAttribute("nthreads", xmlencode(ec.nthreads))
94 ecnode.setAttribute("local_dir", xmlencode(ec.local_dir))
95 ecnode.setAttribute("exp_dir", xmlencode(ec.exp_dir))
97 doc.appendChild(ecnode)
99 for guid, rm in ec._resources.iteritems():
100 self._rm_to_xml(doc, ecnode, ec, guid, rm)
104 def _netgraph_to_xml(self, doc, ecnode, ec):
106 def _rm_to_xml(self, doc, ecnode, ec, guid, rm):
107 rmnode = doc.createElement("rm")
108 rmnode.setAttribute("guid", xmlencode(guid))
109 rmnode.setAttribute("rtype", xmlencode(rm._rtype))
110 rmnode.setAttribute("state", xmlencode(rm._state))
112 rmnode.setAttribute("start_time", xmlencode(rm._start_time))
114 rmnode.setAttribute("stop_time", xmlencode(rm._stop_time))
115 if rm._discover_time:
116 rmnode.setAttribute("discover_time", xmlencode(rm._discover_time))
117 if rm._provision_time:
118 rmnode.setAttribute("provision_time", xmlencode(rm._provision_time))
120 rmnode.setAttribute("ready_time", xmlencode(rm._ready_time))
122 rmnode.setAttribute("release_time", xmlencode(rm._release_time))
124 rmnode.setAttribute("failed_time", xmlencode(rm._failed_time))
125 ecnode.appendChild(rmnode)
127 anode = doc.createElement("attributes")
130 for attr in rm._attrs.values():
133 aanode = doc.createElement("attribute")
134 aanode.setAttribute("name", xmlencode(attr.name))
135 aanode.setAttribute("value", xmlencode(attr.value))
136 aanode.setAttribute("type", from_type(attr.value))
137 anode.appendChild(aanode)
140 rmnode.appendChild(anode)
142 cnode = doc.createElement("connections")
145 for guid in rm._connections:
147 ccnode = doc.createElement("connection")
148 ccnode.setAttribute("guid", xmlencode(guid))
149 cnode.appendChild(ccnode)
152 rmnode.appendChild(cnode)
154 cnnode = doc.createElement("conditions")
157 for action, conds in rm._conditions.iteritems():
159 for (group, state, time) in conds:
160 ccnnode = doc.createElement("condition")
161 ccnnode.setAttribute("action", xmlencode(action))
162 ccnnode.setAttribute("group", xmlencode(group))
163 ccnnode.setAttribute("state", xmlencode(state))
164 ccnnode.setAttribute("time", xmlencode(time))
165 cnnode.appendChild(ccnnode)
168 rmnode.appendChild(cnnode)
170 tnode = doc.createElement("traces")
173 for trace in rm._trcs.values():
176 ttnode = doc.createElement("trace")
177 ttnode.setAttribute("name", xmlencode(trace.name))
178 tnode.appendChild(ttnode)
181 rmnode.appendChild(tnode)
183 def from_xml(self, xml):
184 doc = minidom.parseString(xml)
185 return self._ec_from_xml(doc)
187 def _ec_from_xml(self, doc):
188 from nepi.execution.ec import ExperimentController
191 ecnode_list = doc.getElementsByTagName("experiment")
192 for ecnode in ecnode_list:
193 if ecnode.nodeType == doc.ELEMENT_NODE:
194 exp_id = xmldecode(ecnode.getAttribute("exp_id"))
195 run_id = xmldecode(ecnode.getAttribute("run_id"))
196 local_dir = xmldecode(ecnode.getAttribute("local_dir"))
197 nthreads = xmldecode(ecnode.getAttribute("nthreads"))
199 os.environ["NEPI_NTHREADS"] = nthreads
200 ec = ExperimentController(exp_id = exp_id, local_dir = local_dir)
204 rmnode_list = ecnode.getElementsByTagName("rm")
205 for rmnode in rmnode_list:
206 if rmnode.nodeType == doc.ELEMENT_NODE:
207 self._rm_from_xml(doc, rmnode, ec, connections)
209 for (guid1, guid2) in connections:
210 ec.register_connection(guid1, guid2)
216 def _rm_from_xml(self, doc, rmnode, ec, connections):
220 provision_time = None
225 guid = xmldecode(rmnode.getAttribute("guid"), int)
226 rtype = xmldecode(rmnode.getAttribute("rtype"))
228 # FOR NOW ONLY STATE NEW IS ALLOWED
231 state = xmldecode(rmnode.getAttribute("state"), int)
233 if rmnode.hasAttribute("start_time"):
234 start_time = xmldecode(rmnode.getAttribute("start_time"),
236 if rmnode.hasAttribute("stop_time"):
237 stop_time = xmldecode(rmnode.getAttribute("stop_time"),
239 if rmnode.hasAttribute("discover_time"):
240 dicover_time = xmldecode(rmnode.getAttribute("discover_time"),
242 if rmnode.hasAttribute("provision_time"):
243 provision_time = xmldecode(rmnode.getAttribute("provision_time"),
245 if rmnode.hasAttribute("ready_time"):
246 ready_time = xmldecode(rmnode.getAttribute("ready_time"),
248 if rmnode.hasAttribute("release_time"):
249 release_time = xmldecode(rmnode.getAttribute("release_time"),
251 if rmnode.hasAttribute("failed_time"):
252 failed_time = xmldecode(rmnode.getAttribute("failed_time"),
256 ec.register_resource(rtype, guid = guid)
257 rm = ec.get_resource(guid)
258 rm.set_state_time(state, "_start_time", start_time)
259 rm.set_state_time(state, "_stop_time", stop_time)
260 rm.set_state_time(state, "_discover_time", discover_time)
261 rm.set_state_time(state, "_provision_time", provision_time)
262 rm.set_state_time(state, "_ready_time", ready_time)
263 rm.set_state_time(state, "_release_time", release_time)
264 rm.set_state_time(state, "_failed_time", failed_time)
266 anode_list = rmnode.getElementsByTagName("attributes")
268 aanode_list = anode_list[0].getElementsByTagName("attribute")
269 for aanode in aanode_list:
270 name = xmldecode(aanode.getAttribute("name"))
271 value = xmldecode(aanode.getAttribute("value"))
272 tipe = xmldecode(aanode.getAttribute("type"))
273 value = to_type(tipe, value)
276 cnode_list = rmnode.getElementsByTagName("connections")
278 ccnode_list = cnode_list[0].getElementsByTagName("connection")
279 for ccnode in ccnode_list:
280 guid2 = xmldecode(ccnode.getAttribute("guid"), int)
281 connections.add((guid, guid2))
283 tnode_list = rmnode.getElementsByTagName("traces")
285 ttnode_list = tnode_list[0].getElementsByTagName("trace")
286 for ttnode in ttnode_list:
287 name = xmldecode(ttnode.getAttribute("name"))
288 ec.enable_trace(guid, name)
290 cnnode_list = rmnode.getElementsByTagName("conditions")
292 ccnnode_list = cnnode_list[0].getElementsByTagName("condition")
293 for ccnnode in ccnnode_list:
294 action = xmldecode(ccnnode.getAttribute("action"), int)
295 group = xmldecode(ccnnode.getAttribute("group"), eval)
296 state = xmldecode(ccnnode.getAttribute("state"), int)
297 time = xmldecode(ccnnode.getAttribute("time"))
298 time = to_type('STRING', time)
299 ec.register_condition(guid, action, group, state, time = time)