Commiting improvements to Collector. Local_dir added to ExperimentController
[nepi.git] / examples / ccn_flooding / flooding.py
1 #!/usr/bin/env python
2
3 ###############################################################################
4 #
5 #    NEPI, a framework to manage network experiments
6 #
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.
11 #
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.
16 #
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/>.
19 #
20 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
21 #
22 ###############################################################################
23
24 from nepi.execution.ec import ExperimentController 
25 from nepi.execution.resource import ResourceState, ResourceAction
26 from nepi.util.netgraph import NetGraph, TopologyType
27
28 import os
29 import tempfile
30
31 from dminer import ccn
32
33 PL_NODES = dict({
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"
49     })
50
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")
55
56 content_name = "ccnx:/test/bunny.ts"
57
58 pipeline = 4 # Default value for ccncat
59
60 operating_system = "f14"
61
62 country = "germany"
63
64 repofile = os.path.join(
65         os.path.dirname(os.path.realpath(__file__)),
66             "..", "repoFile1.0.8.2")
67
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)
73     if rename:
74         ec.set(collector, "rename", rename)
75
76     return collector
77
78 def add_node(ec, n):
79     hostname = PL_NODES[n]
80
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)
91
92     return node
93
94 def add_ccnd(ec, node, n):
95     global PL_NODES
96
97     ccnd = ec.register_resource("LinuxCCND")
98     ec.set(ccnd, "debug", 7)
99     ec.register_connection(ccnd, node)
100
101     # collector for ccnd trace
102     hostname = PL_NODES[n]
103     collector = add_collector(ec, "stderr", hostname, "log")
104     ec.register_connection(collector, ccnd)
105
106     PL_NODES[n] = (hostname, node, ccnd)
107     return ccnd
108
109 def add_ccnr(ec, ccnd):
110     ccnr = ec.register_resource("LinuxCCNR")
111
112     ec.set(ccnr, "repoFile1", repofile)
113     ec.register_connection(ccnr, ccnd)
114
115     return ccnr
116
117 def add_fib_entry(ec, n1, n2):
118     (hostname1, node1, ccnd1) = PL_NODES[n1] 
119     (hostname2, node2, ccnd2) = PL_NODES[n2]
120
121     entry = ec.register_resource("LinuxFIBEntry")
122     ec.set(entry, "host", peer_host)
123
124     ec.register_connection(entry, ccnd1)
125
126     ec.enable_trace(entry, "ping")
127     collector = add_collector(ec, "ping", hostname2)
128     ec.register_connection(collector, entry)
129
130     return entry
131
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)
137
138     return ccncat
139
140 def compute_metric_callback(ec, run):
141     ## Process logs and analyse data
142     try:
143         graph = ccn.parse_ccndlogs(graph = graph, 
144                 parse_ping_logs = True)
145     except:
146         print "Skipping: Error parsing ccnd logs", run_dir
147         raise
148
149     source = ccn.consumers(graph)[0]
150     target = ccn.producers(graph)[0]
151
152     # Process the data from the ccnd logs, but do not re compute
153     # the link delay. 
154     try:
155         (content_names,
156             interest_expiry_count,
157             interest_dupnonce_count,
158             interest_count,
159             content_count) = ccn.process_ccn_data(graph, source)
160     except:
161         print "Skipping: Error processing ccn data", run_dir
162         raise
163
164     # Compute the shortest path
165     shortest_path = ccn.shortest_path(graph, source, target)
166
167     # Compute the load coefficient
168     lcoeff = ccn.load_coefficient(graph, shortest_path, content_names)
169
170     return lcoeff
171              
172 if __name__ == '__main__':
173     
174     #### Generate a LADDER network topology 
175     net_graph = NetGraph(topo_type = TopologyType.LADDER, 
176             node_count = 6, 
177             assign_st = True, 
178             assign_ips = True)
179    
180     target = net_graph.targets()[0]
181     source = net_graph.sources()[0]
182     
183     wait_guids = []
184
185     #### Create NEPI Experiment Description (EC)
186     ec = ExperimentController(exp_id)
187
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)
192         
193         if n == target:
194             ccnr = add_ccnr(ec, ccnd)
195
196         ## Add content retrival application
197         if n == source:
198             ccncat = add_ccncat(ec, ccnd)
199             wait_guids.append(ccncat)
200
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)
205
206     #### Define the callback to compute experiment metric
207     metric_callback = functools.partial(compute_metric_callback, ping)
208
209     #### Run experiment until metric convergence
210     rnr = ExperimentRunner()
211
212     runs = rnr.run(ec, min_runs = 10, max_runs = 300 
213             compute_metric_callback = metric_callback,
214             wait_guids = wait_guids,
215             wait_time = 0)
216