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.resource import ResourceState, ResourceAction
26 from nepi.util.netgraph import NetGraph, TopologyType
31 from dminer import ccn
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__)),
66 "..", "repoFile1.0.8.2")
68 def add_collector(ec, trace_name, store_dir, sub_dir, rename = None):
69 collector = ec.register_resource("Collector")
70 ec.set(collector, "traceName", trace_name)
71 ec.set(collector, "storeDir", store_dir)
72 ec.set(collector, "subDir", sub_dir)
74 ec.set(collector, "rename", rename)
79 hostname = PL_NODES[n]
81 node = ec.register_resource("PlanetlabNode")
82 ec.set(node, "hostname", hostname)
83 ec.set(node, "username", username)
84 ec.set(node, "identity", identity)
85 ec.set(node, "pluser", pl_user)
86 ec.set(node, "plpassword", pl_password)
87 #ec.set(node, "country", country)
88 #ec.set(node, "operatingSystem", operating_system)
89 ec.set(node, "cleanExperiment", True)
90 ec.set(node, "cleanProcesses", True)
94 def add_ccnd(ec, node, n):
97 ccnd = ec.register_resource("LinuxCCND")
98 ec.set(ccnd, "debug", 7)
99 ec.register_connection(ccnd, node)
101 # collector for ccnd trace
102 hostname = PL_NODES[n]
103 collector = add_collector(ec, "stderr", hostname, "log")
104 ec.register_connection(collector, ccnd)
106 PL_NODES[n] = (hostname, node, ccnd)
109 def add_ccnr(ec, ccnd):
110 ccnr = ec.register_resource("LinuxCCNR")
112 ec.set(ccnr, "repoFile1", repofile)
113 ec.register_connection(ccnr, ccnd)
117 def add_fib_entry(ec, n1, n2):
118 (hostname1, node1, ccnd1) = PL_NODES[n1]
119 (hostname2, node2, ccnd2) = PL_NODES[n2]
121 entry = ec.register_resource("LinuxFIBEntry")
122 ec.set(entry, "host", peer_host)
124 ec.register_connection(entry, ccnd1)
126 ec.enable_trace(entry, "ping")
127 collector = add_collector(ec, "ping", hostname2)
128 ec.register_connection(collector, entry)
132 def add_ccncat(ec, ccnd):
133 ccncat = ec.register_resource("LinuxCCNCat")
134 ec.set(ccncat, "pipeline", pipeline)
135 ec.set(ccncat, "contentName", content_name)
136 ec.register_connection(ccncat, ccnd)
140 def compute_metric_callback(ec, run):
141 ## Process logs and analyse data
143 graph = ccn.parse_ccndlogs(graph = graph,
144 parse_ping_logs = True)
146 print "Skipping: Error parsing ccnd logs", run_dir
149 source = ccn.consumers(graph)[0]
150 target = ccn.producers(graph)[0]
152 # Process the data from the ccnd logs, but do not re compute
156 interest_expiry_count,
157 interest_dupnonce_count,
159 content_count) = ccn.process_ccn_data(graph, source)
161 print "Skipping: Error processing ccn data", run_dir
164 # Compute the shortest path
165 shortest_path = ccn.shortest_path(graph, source, target)
167 # Compute the load coefficient
168 lcoeff = ccn.load_coefficient(graph, shortest_path, content_names)
172 if __name__ == '__main__':
174 #### Generate a LADDER network topology
175 net_graph = NetGraph(topo_type = TopologyType.LADDER,
180 target = net_graph.targets()[0]
181 source = net_graph.sources()[0]
185 #### Create NEPI Experiment Description (EC)
186 ec = ExperimentController(exp_id)
188 ### Add CCN nodes to the (EC)
189 for n in graph.nodes():
190 node = add_node(ec, n)
191 ccnd = add_ccnd(ec, node, n)
194 ccnr = add_ccnr(ec, ccnd)
196 ## Add content retrival application
198 ccncat = add_ccncat(ec, ccnd)
199 wait_guids.append(ccncat)
201 #### Add connections between CCN nodes
202 for n1, n2 in graph.edges():
203 add_fib_entry(ec, n1, n2)
204 add_fib_entry(ec, n2, n1)
206 #### Define the callback to compute experiment metric
207 metric_callback = functools.partial(compute_metric_callback, ping)
209 #### Run experiment until metric convergence
210 rnr = ExperimentRunner()
212 runs = rnr.run(ec, min_runs = 10, max_runs = 300
213 compute_metric_callback = metric_callback,
214 wait_guids = wait_guids,