3 ###############################################################################
5 # NEPI, a framework to manage network experiments
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
22 ###############################################################################
24 from nepi.execution.ec import ExperimentController
25 from nepi.execution.runner import ExperimentRunner
26 from nepi.util.netgraph import NetGraph, TopologyType
27 import nepi.data.processing.ccn.parser as ccn_parser
34 "0": "iraplab1.iralab.uni-karlsruhe.de",
35 "1": "planetlab1.informatik.uni-goettingen.de",
36 "2": "dfn-ple1.x-win.dfn.de",
37 "3": "mars.planetlab.haw-hamburg.de",
38 "4": "planetlab2.unineuchatel.ch",
39 "5": "planetlab-node3.it-sudparis.eu",
40 "6": "planetlab2.extern.kuleuven.be",
41 "7": "node2pl.planet-lab.telecom-lille1.eu",
42 "8": "planetvs2.informatik.uni-stuttgart.de",
43 "9": "planetlab1.informatik.uni-wuerzburg.de",
44 "10": "planet1.l3s.uni-hannover.de",
45 "11": "planetlab1.wiwi.hu-berlin.de",
46 "12": "pl2.uni-rostock.de",
47 "13": "planetlab1.u-strasbg.fr",
48 "14": "peeramidion.irisa.fr"
51 pl_slice = os.environ.get("PL_SLICE")
52 pl_user = os.environ.get("PL_USER")
53 pl_password = os.environ.get("PL_PASS")
54 pl_ssh_key = os.environ.get("PL_SSHKEY")
56 content_name = "ccnx:/test/bunny.ts"
58 pipeline = 4 # Default value for ccncat
60 operating_system = "f14"
64 repofile = os.path.join(
65 os.path.dirname(os.path.realpath(__file__)), "repoFile1.0.8.2")
67 def add_collector(ec, trace_name, subdir, newname = None):
68 collector = ec.register_resource("Collector")
69 ec.set(collector, "traceName", trace_name)
70 ec.set(collector, "subDir", subdir)
72 ec.set(collector, "rename", newname)
76 def add_pl_host(ec, nid):
77 hostname = PL_NODES[nid]
79 # Add a planetlab host to the experiment description
80 host = ec.register_resource("PlanetlabNode")
81 ec.set(host, "hostname", hostname)
82 ec.set(host, "username", pl_slice)
83 ec.set(host, "identity", pl_ssh_key)
84 #ec.set(host, "pluser", pl_user)
85 #ec.set(host, "plpassword", pl_password)
86 #ec.set(host, "country", country)
87 #ec.set(host, "operatingSystem", operating_system)
88 ec.set(host, "cleanExperiment", True)
89 ec.set(host, "cleanProcesses", True)
92 ec.netgraph.annotate_node(nid, "hostname", hostname)
93 ec.netgraph.annotate_node(nid, "host", host)
95 # Annotate the graph node with an ip address
96 ip = socket.gethostbyname(hostname)
97 ec.netgraph.annotate_node_ip(nid, ip)
99 def add_pl_ccnd(ec, nid):
100 # Retrieve annotation from netgraph
101 host = ec.netgraph.node_annotation(nid, "host")
103 # Add a CCN daemon to the planetlab node
104 ccnd = ec.register_resource("LinuxCCND")
105 ec.set(ccnd, "debug", 7)
106 ec.register_connection(ccnd, host)
108 # Collector to retrieve ccnd log
109 collector = add_collector(ec, "stderr", nid, "log")
110 ec.register_connection(collector, ccnd)
113 ec.netgraph.annotate_node(nid, "ccnd", ccnd)
115 def add_pl_ccnr(ec, nid):
116 # Retrieve annotation from netgraph
117 ccnd = ec.netgraph.node_annotation(nid, "ccnd")
119 # Add a CCN content repository to the planetlab node
120 ccnr = ec.register_resource("LinuxCCNR")
122 ec.set(ccnr, "repoFile1", repofile)
123 ec.register_connection(ccnr, ccnd)
125 def add_pl_ccncat(ec, nid):
126 # Retrieve annotation from netgraph
127 ccnd = ec.netgraph.node_annotation(nid, "ccnd")
129 # Add a CCN cat application to the planetlab node
130 ccncat = ec.register_resource("LinuxCCNCat")
131 ec.set(ccncat, "pipeline", pipeline)
132 ec.set(ccncat, "contentName", content_name)
133 ec.register_connection(ccncat, ccnd)
135 def add_pl_fib_entry(ec, nid1, nid2):
136 # Retrieve annotations from netgraph
137 ccnd1 = ec.netgraph.node_annotation(nid1, "ccnd")
138 hostname2 = ec.netgraph.node_annotation(nid2, "hostname")
140 # Add a FIB entry between one planetlab node and its peer
141 entry = ec.register_resource("LinuxFIBEntry")
142 ec.set(entry, "host", hostname2)
143 ec.register_connection(entry, ccnd1)
145 # Collector to retrieve peering ping output (to measure neighbors delay)
146 ec.enable_trace(entry, "ping")
147 collector = add_collector(ec, "ping", nid1)
148 ec.register_connection(collector, entry)
152 def avg_interests(ec, run):
154 logs_dir = ec.run_dir
158 interest_expiry_count,
159 interest_dupnonce_count,
161 content_count) = ccn_parser.process_content_history_logs(
163 ec.netgraph.topology)
165 shortest_path = networkx.shortest_path(graph,
166 source = ec.netgraph.sources()[0],
167 target = ec.netgraph.targets()[0])
169 ### Compute metric: Avg number of Interests seen per content name
170 ### normalized by the number of nodes in the shortest path
171 content_name_count = len(content_names.values())
172 nodes_in_shortest_path = len(shortest_path) - 1
173 metric = interest_count / (float(content_name_count) * float(nodes_in_shortest_path))
175 # TODO: DUMP RESULTS TO FILE
176 # TODO: DUMP GRAPH DELAYS!
177 f = open("/tmp/metric", "w+")
178 f.write("%.2f\n" % metric)
180 print " METRIC", metric
184 def add_pl_edge(ec, nid1, nid2):
185 #### Add connections between CCN nodes
186 add_pl_fib_entry(ec, nid1, nid2)
187 add_pl_fib_entry(ec, nid2, nid1)
189 def add_pl_node(ec, nid):
190 ### Add CCN nodes (ec.netgraph holds the topology graph)
194 if nid == ec.netgraph.targets()[0]:
197 if nid == ec.netgraph.sources()[0]:
198 add_pl_ccncat(ec, nid)
200 if __name__ == '__main__':
202 #### Create NEPI Experiment Description with LINEAR topology
203 ec = ExperimentController("pl_ccn",
204 topo_type = TopologyType.LINEAR,
208 add_node_callback = add_pl_node,
209 add_edge_callback = add_pl_edge)
211 print "Results stored at", ec.exp_dir
213 #### Retrieve the content producing resource to wait for ot to finish
214 ccncat = ec.filter_resources("LinuxCCNCat")
216 #### Run experiment until metric convergences
217 rnr = ExperimentRunner()
218 runs = rnr.run(ec, min_runs = 10, max_runs = 300,
219 compute_metric_callback = avg_interests,