from nepi.util.netgraph import NetGraph, TopologyType
import nepi.data.processing.ccn.parser as ccn_parser
+import networkx
import socket
import os
## Process logs
logs_dir = ec.run_dir
- print ec.netgraph
-
(graph,
content_names,
interest_expiry_count,
interest_count,
content_count) = ccn_parser.process_content_history_logs(
logs_dir,
- ec.netgraph)
+ ec.netgraph.topology)
shortest_path = networkx.shortest_path(graph,
source = ec.netgraph.sources()[0],
### Compute metric: Avg number of Interests seen per content name
### normalized by the number of nodes in the shortest path
content_name_count = len(content_names.values())
- nodes_in_shortest_path = len(content_names.values())
- metric = interest_count / float(content_name_count) / float(nodes_in_shortest_path)
+ nodes_in_shortest_path = len(shortest_path) - 1
+ metric = interest_count / (float(content_name_count) * float(nodes_in_shortest_path))
# TODO: DUMP RESULTS TO FILE
# TODO: DUMP GRAPH DELAYS!
+ f = open("/tmp/metric", "w+")
+ f.write("%.2f\n" % metric)
+ f.close()
+ print " METRIC", metric
return metric
# If no external IP address was identified for this face
# asume it is a local face
- hostip = "localhost"
+ peer = "localhost"
if face_id in faces:
- hostip, port = faces[face_id]
+ peer, port = faces[face_id]
- data.append((content_name, timestamp, message_type, hostip, face_id,
+ data.append((content_name, timestamp, message_type, peer, face_id,
size, nonce, line))
f.close()
return content_history
def annotate_cn_node(graph, nid, ips2nid, data, content_history):
- for (content_name, timestamp, message_type, hostip, face_id,
+ for (content_name, timestamp, message_type, peer, face_id,
size, nonce, line) in data:
- # Ignore local messages for the time being.
- # They could later be used to calculate the processing times
- # of messages.
- if peer == "localhost":
- return
-
# Ignore control messages for the time being
if is_control(content_name):
- return
+ continue
if message_type == "interest_from" and \
peer == "localhost":
peer == "localhost":
graph.node[nid]["ccn_producer"] = True
+ # Ignore local messages for the time being.
+ # They could later be used to calculate the processing times
+ # of messages.
+ if peer == "localhost":
+ continue
+
# remove digest
if message_type in ["content_from", "content_to"]:
content_name = "/".join(content_name.split("/")[:-1])
content_history[content_name] = list()
peernid = ips2nid[peer]
- add_edge(graph, nid, peernid)
+ graph.add_edge(nid, peernid)
content_history[content_name].append((timestamp, message_type, nid,
peernid, nonce, size, line))
# Make a copy of the graph to ensure integrity
graph = graph.copy()
- ips2nids = dict()
+ ips2nid = dict()
for nid in graph.nodes():
ips = graph.node[nid]["ips"]
for ip in ips:
- ips2nids[ip] = nid
+ ips2nid[ip] = nid
# Now walk through the ccnd logs...
for dirpath, dnames, fnames in os.walk(logs_dir):
if fname.endswith(".log"):
filename = os.path.join(dirpath, fname)
data = parse_file(filename)
- annotate_cn_node(graph, nid, ips2nids, data, content_history)
+ annotate_cn_node(graph, nid, ips2nid, data, content_history)
# Avoid storing everything in memory, instead dump to a file
# and reference the file
content_names[content_name]["rtt"] = rtt
content_names[content_name]["lapse"] = (interest_timestamp, content_timestamp)
- return (content_names,
+ return (graph,
+ content_names,
interest_expiry_count,
interest_dupnonce_count,
interest_count,
print "Skipping: Error parsing ccnd logs", logs_dir
raise
- source = consumers(graph)[0]
- target = producers(graph)[0]
+ source = ccn_consumers(graph)[0]
+ target = ccn_producers(graph)[0]
# Process the data from the ccnd logs, but do not re compute
# the link delay.
# This library contains functions to parse log files generated using ping.
#
+import collections
import re
+import os
# RE to match line starting "traceroute to"
_rre = re.compile("\d+ bytes from ((?P<hostname>[^\s]+) )?\(?(?P<ip>[^\s]+)\)??: icmp_.eq=\d+ ttl=\d+ time=(?P<time>[^\s]+) ms")
return data
-def annotate_cn_node(graph, nid1, ips2nids, data):
+def annotate_cn_node(graph, nid1, ips2nid, data):
for (target_ip, target_hostname, time) in data:
nid2 = ips2nid[target_ip]
ping.
"""
- ips2nids = dict()
+ ips2nid = dict()
for nid in graph.nodes():
ips = graph.node[nid]["ips"]
for ip in ips:
- ips2nids[ip] = nid
+ ips2nid[ip] = nid
# Walk through the ping logs...
for dirpath, dnames, fnames in os.walk(logs_dir):
if fname.endswith(".ping"):
filename = os.path.join(dirpath, fname)
data = parse_file(filename)
- annotate_cn_node(graph, nid, ips2nids, data)
+ annotate_cn_node(graph, nid, ips2nid, data)
# Take as weight the most frequent value
for nid1, nid2 in graph.edges():
# Local path where to store experiment related files (results, etc)
if not local_dir:
- local_dir = tempfile.mkdtemp()
+ local_dir = tempfile.gettempdir() # /tmp
self._local_dir = local_dir
self._exp_dir = os.path.join(local_dir, self.exp_id)
# Automatically construct experiment description
self._netgraph = None
- if add_node_callback and add_edge_callback:
+ if add_node_callback or add_edge_callback or kwargs.get("topology"):
self._build_from_netgraph(add_node_callback, add_edge_callback,
**kwargs)
return sec
def save(self, dirpath = None, format = SFormats.XML):
+ if dirpath == None:
+ dirpath = self.run_dir
+
+ try:
+ os.makedirs(dirpath)
+ except OSError:
+ pass
+
serializer = ECSerializer()
- path = serializer.save(self, dirpath = None, format = format)
+ path = serializer.save(self, dirpath, format = format)
return path
def get_task(self, tid):
self.wait_released(guids)
if self.persist:
- self.save(dirpath = self.run_dir)
+ self.save()
for guid in guids:
if self.get(guid, "hardRelease"):
"""
self._netgraph = NetGraph(**kwargs)
- ### Add resources to the EC
- for nid in self.netgraph.graph.nodes():
- add_node_callback(self, nid)
-
- #### Add connections between resources
- for nid1, nid2 in self.netgraph.graph.edges():
- add_edge_callback(self, nid1, nid2)
+ if add_node_callback:
+ ### Add resources to the EC
+ for nid in self.netgraph.nodes():
+ add_node_callback(self, nid)
+ if add_edge_callback:
+ #### Add connections between resources
+ for nid1, nid2 in self.netgraph.edges():
+ add_edge_callback(self, nid1, nid2)
import traceback
err = traceback.format_exc()
- msg = " %s guid %d ----- FAILED TO RELEASED ----- \n %s " % (
+ msg = " %s guid %d ----- FAILED TO RELEASE ----- \n %s " % (
self._rtype, self.guid, err)
logger = Logger(self._rtype)
logger.debug(msg)
import math
import numpy
import os
-import tempfile
import time
class ExperimentRunner(object):
# Force persistence of experiment controller
ec._persist = True
- dirpath = tempfile.mkdtemp()
- filepath = ec.save(dirpath)
+ filepath = ec.save(dirpath = ec.exp_dir)
samples = []
run = 0
- while True:
+ stop = False
+
+ while not stop:
run += 1
ec = self.run_experiment(filepath, wait_time, wait_guids)
ec.logger.info(" RUN %d \n" % run)
- if run >= min_runs and max_runs > -1 and run >= max_runs :
- break
-
if compute_metric_callback:
metric = compute_metric_callback(ec, run)
if metric is not None:
if run >= min_runs and evaluate_convergence_callback:
if evaluate_convergence_callback(ec, run, samples):
- break
+ stop = True
+
+ if run >= min_runs and max_runs > -1 and run >= max_runs :
+ stop = True
+
del ec
return run
rms = self.get_connected()
for rm in rms:
- result = self.ec.trace(rm.guid, trace_name)
fpath = os.path.join(self.store_path, "%d.%s" % (rm.guid,
- rename))
+ rename))
+
try:
+ result = self.ec.trace(rm.guid, trace_name)
f = open(fpath, "w")
f.write(result)
f.close()
if (proc and proc.poll()) or err:
msg = " Failed to STOP command '%s' " % self.get("command")
self.error(msg, out, err)
-
+
super(LinuxApplication, self).do_stop()
def do_release(self):
if name == "ping":
if not self.ping:
return None
- return self.ec.trace(self.ping, "stdout", attr, block, offset)
+ return self.ec.trace(self.ping.guid, "stdout", attr, block, offset)
if name == "traceroute":
if not self.traceroute:
return None
- return self.ec.trace(self.traceroute, "stdout", attr, block, offset)
+ return self.ec.trace(self.traceroute.guid, "stdout", attr, block, offset)
return super(LinuxFIBEntry, self).trace(name, attr, block, offset)
self.ec.set(traceroute, "target", self.get("host"))
self.ec.set(traceroute, "earlyStart", True)
self.ec.register_connection(traceroute, self.node.guid)
+ self.ec.register_connection(traceroute, self.guid)
# schedule mtr deploy
self.ec.deploy(guids=[traceroute], group = self.deployment_group)
""" A graph can be generated using a specified pattern
(LADDER, MESH, TREE, etc), or provided as an argument.
- :param graph: Undirected graph to use as internal representation
- :type graph: networkx.Graph
+ :param topology: Undirected graph to use as internal representation
+ :type topology: networkx.Graph
:param topo_type: One of TopologyType.{LINEAR,LADDER,MESH,TREE,STAR}
used to automatically generate the topology graph.
edge (hyperedge) can not be modeled for the moment).
"""
- self._graph = kwargs.get("graph")
- self._topo_type = TopologyType.ADHOC
+ self._topology = kwargs.get("topology")
+ self._topo_type = kwargs.get("topo_type", TopologyType.ADHOC)
- if not self._graph and kwargs.get("topo_type") and \
- kwargs.get("node_count"):
- topo_type = kwargs["topo_type"]
- node_count = kwargs["node_count"]
- branches = kwargs.get("branches")
+ if not self.topology:
+ if kwargs.get("node_count"):
+ node_count = kwargs["node_count"]
+ branches = kwargs.get("branches")
- self._topo_type = topo_type
- self._graph = self.generate_graph(topo_type, node_count,
- branches = branches)
+ self._topology = self.generate_topology(self.topo_type,
+ node_count, branches = branches)
+ else:
+ self._topology = networkx.Graph()
if kwargs.get("assign_ips"):
network = kwargs.get("network", "10.0.0.0")
prefix = kwargs.get("prefix", 8)
version = kwargs.get("version", 4)
- self.assign_p2p_ips(self, network = network, prefix = prefix,
+ self.assign_p2p_ips(network = network, prefix = prefix,
version = version)
if kwargs.get("assign_st"):
self.select_random_leaf_source()
@property
- def graph(self):
- return self._graph
+ def topology(self):
+ return self._topology
@property
def topo_type(self):
@property
def order(self):
- return self.graph.order()
+ return self.topology.order()
- @property
def nodes(self):
- return self.graph.nodes()
+ return self.topology.nodes()
- @property
def edges(self):
- return self.graph.edges()
+ return self.topology.edges()
- def generate_graph(self, topo_type, node_count, branches = None):
+ def generate_topology(self, topo_type, node_count, branches = None):
if topo_type == TopologyType.LADDER:
total_nodes = node_count/2
graph = networkx.ladder_graph(total_nodes)
def add_node(self, nid):
nid = str(nid)
- if nid not in self.graph:
- self.graph.add_node(nid)
+ if nid not in self.topology:
+ self.topology.add_node(nid)
def add_edge(self, nid1, nid2):
nid1 = str(nid1)
self.add_node(nid1)
self.add_node( nid2)
- if nid1 not in self.graph[nid2]:
- self.graph.add_edge(nid2, nid1)
-
- # The weight of the edge is the delay of the link
- self.graph.edge[nid1][nid2]["weight"] = None
- # confidence interval of the mean RTT
- self.graph.edge[nid1][nid2]["weight_ci"] = None
+ if nid1 not in self.topology[nid2]:
+ self.topology.add_edge(nid2, nid1)
def annotate_node_ip(self, nid, ip):
- if "ips" not in self.graph.node[nid]:
- self.graph.node[nid]["ips"] = list()
-
- self.graph.node[nid]["ips"].append(ip)
-
+ if "ips" not in self.topology.node[nid]:
+ self.topology.node[nid]["ips"] = list()
+
+ self.topology.node[nid]["ips"].append(ip)
+
+ def node_ip_annotations(self, nid):
+ return self.topology.node[nid].get("ips", [])
+
def annotate_node(self, nid, name, value):
- self.graph.node[nid][name] = value
+ if not isinstance(value, str) and not isinstance(value, int) and \
+ not isinstance(value, float) and not isinstance(value, bool):
+ raise RuntimeError, "Non-serializable annotation"
+
+ self.topology.node[nid][name] = value
def node_annotation(self, nid, name):
- return self.graph.node[nid].get(name)
+ return self.topology.node[nid].get(name)
+
+ def node_annotations(self, nid):
+ return self.topology.node[nid].keys()
def del_node_annotation(self, nid, name):
- del self.graph.node[nid][name]
+ del self.topology.node[nid][name]
def annotate_edge(self, nid1, nid2, name, value):
- self.graph.edge[nid1][nid2][name] = value
-
+ if not isinstance(value, str) and not isinstance(value, int) and \
+ not isinstance(value, float) and not isinstance(value, bool):
+ raise RuntimeError, "Non-serializable annotation"
+
+ self.topology.edge[nid1][nid2][name] = value
+
+ def annotate_edge_net(self, nid1, nid2, ip1, ip2, mask, network,
+ prefixlen):
+ self.topology.edge[nid1][nid2]["net"] = dict()
+ self.topology.edge[nid1][nid2]["net"][nid1] = ip1
+ self.topology.edge[nid1][nid2]["net"][nid2] = ip2
+ self.topology.edge[nid1][nid2]["net"]["mask"] = mask
+ self.topology.edge[nid1][nid2]["net"]["network"] = network
+ self.topology.edge[nid1][nid2]["net"]["prefix"] = prefixlen
+
+ def edge_net_annotation(self, nid1, nid2):
+ return self.topology.edge[nid1][nid2].get("net", dict())
+
def edge_annotation(self, nid1, nid2, name):
- return self.graph.edge[nid1][nid2].get(name)
+ return self.topoplogy.edge[nid1][nid2].get(name)
+
+ def edge_annotations(self, nid1, nid2):
+ return self.topology.edge[nid1][nid2].keys()
def del_edge_annotation(self, nid1, nid2, name):
- del self.graph.edge[nid1][nid2][name]
+ del self.topology.edge[nid1][nid2][name]
def assign_p2p_ips(self, network = "10.0.0.0", prefix = 8, version = 4):
""" Assign IP addresses to each end of each edge of the network graph,
:type version: int
"""
- if len(networkx.connected_components(self.graph)) > 1:
+ if networkx.number_connected_components(self.topology) > 1:
raise RuntimeError("Disconnected graph!!")
# Assign IP addresses to host
raise RuntimeError, "Invalid IP version %d" % version
## Clear all previusly assigned IPs
- for nid in self.graph.node():
- self.graph.node[nid]["ips"] = list()
+ for nid in self.topology.nodes():
+ self.topology.node[nid]["ips"] = list()
## Generate and assign new IPs
sub_itr = net.iter_subnets(new_prefix = new_prefix)
- for nid1, nid2 in self.graph.edges():
+ for nid1, nid2 in self.topology.edges():
#### Compute subnets for each link
# get a subnet of base_add with prefix /30
ip1 = addr1.exploded
ip2 = addr2.exploded
- self.graph.edge[nid1][nid2]["net"] = dict()
- self.graph.edge[nid1][nid2]["net"][nid1] = ip1
- self.graph.edge[nid1][nid2]["net"][nid2] = ip2
- self.graph.edge[nid1][nid2]["net"]["mask"] = mask
- self.graph.edge[nid1][nid2]["net"]["network"] = mask
- self.graph.edge[nid1][nid2]["net"]["prefix"] = prefixlen
+ self.annotate_edge_net(nid1, nid2, ip1, ip2, mask, network,
+ prefixlen)
self.annotate_node_ip(nid1, ip1)
self.annotate_node_ip(nid2, ip2)
def get_p2p_info(self, nid1, nid2):
- net = self.graph.edge[nid1][nid2]["net"]
+ net = self.topology.edge[nid1][nid2]["net"]
return ( net[nid1], net[nid2], net["mask"], net["network"],
net["prefixlen"] )
def set_source(self, nid):
- self.graph.node[nid]["source"] = True
+ self.topology.node[nid]["source"] = True
+
+ def is_source(self, nid):
+ return self.topology.node[nid].get("source")
def set_target(self, nid):
- self.graph.node[nid]["target"] = True
+ self.topology.node[nid]["target"] = True
+
+ def is_target(self, nid):
+ return self.topology.node[nid].get("target")
def targets(self):
""" Returns the nodes that are targets """
- return [nid for nid in self.graph.nodes() \
- if self.graph.node[nid].get("target")]
+ return [nid for nid in self.topology.nodes() \
+ if self.topology.node[nid].get("target")]
def sources(self):
""" Returns the nodes that are sources """
- return [nid for nid in self.graph.nodes() \
- if self.graph.node[nid].get("source")]
+ return [nid for nid in self.topology.nodes() \
+ if self.topology.node[nid].get("source")]
def select_target_zero(self):
""" Marks the node 0 as target
source = leaves.pop(random.randint(0, len(leaves) - 1))
else:
# options must not be already sources or targets
- options = [ k for k,v in self.graph.degree().iteritems() \
- if v == 1 and not self.graph.node[k].get("source") \
- and not self.graph.node[k].get("target")]
+ options = [ k for k,v in self.topology.degree().iteritems() \
+ if v == 1 and not self.topology.node[k].get("source") \
+ and not self.topology.node[k].get("target")]
source = options.pop(random.randint(0, len(options) - 1))
#
# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+from nepi.util.netgraph import NetGraph, TopologyType
from nepi.util.timefuncs import stformat, tsformat
from xml.dom import minidom
ecnode.setAttribute("run_id", xmlencode(ec.run_id))
ecnode.setAttribute("nthreads", xmlencode(ec.nthreads))
ecnode.setAttribute("local_dir", xmlencode(ec.local_dir))
- ecnode.setAttribute("exp_dir", xmlencode(ec.exp_dir))
-
doc.appendChild(ecnode)
+ if ec.netgraph != None:
+ self._netgraph_to_xml(doc, ecnode, ec)
+
+ rmsnode = doc.createElement("rms")
+ ecnode.appendChild(rmsnode)
+
for guid, rm in ec._resources.iteritems():
- self._rm_to_xml(doc, ecnode, ec, guid, rm)
+ self._rm_to_xml(doc, rmsnode, ec, guid, rm)
return doc
def _netgraph_to_xml(self, doc, ecnode, ec):
-
- def _rm_to_xml(self, doc, ecnode, ec, guid, rm):
+ ngnode = doc.createElement("topology")
+ ngnode.setAttribute("topo-type", xmlencode(ec.netgraph.topo_type))
+ ecnode.appendChild(ngnode)
+
+ self. _netgraph_nodes_to_xml(doc, ngnode, ec)
+ self. _netgraph_edges_to_xml(doc, ngnode, ec)
+
+ def _netgraph_nodes_to_xml(self, doc, ngnode, ec):
+ ngnsnode = doc.createElement("nodes")
+ ngnode.appendChild(ngnsnode)
+
+ for nid in ec.netgraph.nodes():
+ ngnnode = doc.createElement("node")
+ ngnnode.setAttribute("nid", xmlencode(nid))
+ ngnsnode.appendChild(ngnnode)
+
+ # Mark ources and targets
+ if ec.netgraph.is_source(nid):
+ ngnnode.setAttribute("source", xmlencode(True))
+
+ if ec.netgraph.is_target(nid):
+ ngnnode.setAttribute("target", xmlencode(True))
+
+ # Node annotations
+ annosnode = doc.createElement("node-annotations")
+ add_annotations = False
+ for name in ec.netgraph.node_annotations(nid):
+ add_annotations = True
+ value = ec.netgraph.node_annotation(nid, name)
+ annonode = doc.createElement("node-annotation")
+ annonode.setAttribute("name", xmlencode(name))
+ annonode.setAttribute("value", xmlencode(value))
+ annonode.setAttribute("type", from_type(value))
+ annosnode.appendChild(annonode)
+
+ if add_annotations:
+ ngnnode.appendChild(annosnode)
+
+ def _netgraph_edges_to_xml(self, doc, ngnode, ec):
+ ngesnode = doc.createElement("edges")
+ ngnode.appendChild(ngesnode)
+
+ for nid1, nid2 in ec.netgraph.edges():
+ ngenode = doc.createElement("edge")
+ ngenode.setAttribute("nid1", xmlencode(nid1))
+ ngenode.setAttribute("nid2", xmlencode(nid2))
+ ngesnode.appendChild(ngenode)
+
+ # Edge annotations
+ annosnode = doc.createElement("edge-annotations")
+ add_annotations = False
+ for name in ec.netgraph.edge_annotations(nid1, nid2):
+ add_annotations = True
+ value = ec.netgraph.edge_annotation(nid1, nid2, name)
+ annonode = doc.createElement("edge-annotation")
+ annonode.setAttribute("name", xmlencode(name))
+ annonode.setAttribute("value", xmlencode(value))
+ annonode.setAttribute("type", from_type(value))
+ annosnode.appendChild(annonode)
+
+ if add_annotations:
+ ngenode.appendChild(annosnode)
+
+ def _rm_to_xml(self, doc, rmsnode, ec, guid, rm):
rmnode = doc.createElement("rm")
rmnode.setAttribute("guid", xmlencode(guid))
rmnode.setAttribute("rtype", xmlencode(rm._rtype))
rmnode.setAttribute("release_time", xmlencode(rm._release_time))
if rm._failed_time:
rmnode.setAttribute("failed_time", xmlencode(rm._failed_time))
- ecnode.appendChild(rmnode)
+ rmsnode.appendChild(rmnode)
anode = doc.createElement("attributes")
attributes = False
exp_id = xmldecode(ecnode.getAttribute("exp_id"))
run_id = xmldecode(ecnode.getAttribute("run_id"))
local_dir = xmldecode(ecnode.getAttribute("local_dir"))
+
+ # Configure number of preocessing threads
nthreads = xmldecode(ecnode.getAttribute("nthreads"))
-
os.environ["NEPI_NTHREADS"] = nthreads
- ec = ExperimentController(exp_id = exp_id, local_dir = local_dir)
+
+ # Deserialize netgraph
+ netgraph = self._netgraph_from_xml(doc, ecnode)
+ topo_type = netgraph.topo_type if netgraph else None
+
+ # Instantiate EC
+ ec = ExperimentController(exp_id = exp_id, local_dir = local_dir,
+ topology = netgraph.topology, topo_type = topo_type)
connections = set()
- rmnode_list = ecnode.getElementsByTagName("rm")
- for rmnode in rmnode_list:
- if rmnode.nodeType == doc.ELEMENT_NODE:
- self._rm_from_xml(doc, rmnode, ec, connections)
+ rmsnode_list = ecnode.getElementsByTagName("rms")
+ if rmsnode_list:
+ rmnode_list = rmsnode_list[0].getElementsByTagName("rm")
+ for rmnode in rmnode_list:
+ if rmnode.nodeType == doc.ELEMENT_NODE:
+ self._rm_from_xml(doc, rmnode, ec, connections)
for (guid1, guid2) in connections:
ec.register_connection(guid1, guid2)
return ec
+ def _netgraph_from_xml(self, doc, ecnode):
+ netgraph = None
+
+ topology = ecnode.getElementsByTagName("topology")
+ if topology:
+ topology = topology[0]
+ topo_type = xmldecode(topology.getAttribute("topo-type"))
+
+ netgraph = NetGraph(topo_type = topo_type)
+
+ ngnsnode_list = topology.getElementsByTagName("nodes")
+ if ngnsnode_list:
+ ngnsnode = ngnsnode_list[0].getElementsByTagName("node")
+ for ngnnode in ngnsnode:
+ nid = xmldecode(ngnnode.getAttribute("nid"))
+ netgraph.add_node(nid)
+
+ if ngnnode.hasAttribute("source"):
+ netgraph.set_source(nid)
+ if ngnnode.hasAttribute("target"):
+ netgraph.set_target(nid)
+
+ annosnode_list = ngnnode.getElementsByTagName("node-annotations")
+
+ if annosnode_list:
+ annosnode = annosnode_list[0].getElementsByTagName("node-annotation")
+ for annonode in annosnode:
+ name = xmldecode(annonode.getAttribute("name"))
+
+ if name == "ips":
+ ips = xmldecode(annonode.getAttribute("value"), eval) # list
+ for ip in ips:
+ netgraph.annotate_node_ip(nid, ip)
+ else:
+ value = xmldecode(annonode.getAttribute("value"))
+ tipe = xmldecode(annonode.getAttribute("type"))
+ value = to_type(tipe, value)
+ netgraph.annotate_node(nid, name, value)
+
+ ngesnode_list = topology.getElementsByTagName("edges")
+ if ngesnode_list:
+ ngesnode = ngesnode_list[0].getElementsByTagName("edge")
+ for ngenode in ngesnode:
+ nid1 = xmldecode(ngenode.getAttribute("nid1"))
+ nid2 = xmldecode(ngenode.getAttribute("nid2"))
+ netgraph.add_edge(nid1, nid2)
+
+ annosnode_list = ngenode.getElementsByTagName("edge-annotations")
+ if annosnode_list:
+ annosnode = annosnode_list[0].getElementsByTagName("edge-annotation")
+ for annonode in annosnode:
+ name = xmldecode(annonode.getAttribute("name"))
+
+ if name == "net":
+ net = xmldecode(annonode.getAttribute("value"), eval) # dict
+ netgraph.annotate_edge_net(net[nid1], net[nid2], net["ip1"],
+ net["ip2"], net["mask"], net["network"], net["prefix"])
+ else:
+ value = xmldecode(annonode.getAttribute("value"))
+ tipe = xmldecode(annonode.getAttribute("type"))
+ value = to_type(tipe, value)
+ netgraph.annotate_edge(nid1, nid2, name, value)
+ return netgraph
+
def _rm_from_xml(self, doc, rmnode, ec, connections):
start_time = None
stop_time = None
ccnnode_list = cnnode_list[0].getElementsByTagName("condition")
for ccnnode in ccnnode_list:
action = xmldecode(ccnnode.getAttribute("action"), int)
- group = xmldecode(ccnnode.getAttribute("group"), eval)
+ group = xmldecode(ccnnode.getAttribute("group"), eval) # list
state = xmldecode(ccnnode.getAttribute("state"), int)
time = xmldecode(ccnnode.getAttribute("time"))
time = to_type('STRING', time)
return sec
- def save(self, ec, dirpath = None, format = SFormats.XML):
- if not dirpath:
- import tempfile
- dirpath = tempfile.mkdtemp()
-
+ def save(self, ec, dirpath, format = SFormats.XML):
date = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
filename = "%s_%s" % (ec.exp_id, date)