Nitos OMF ping examples
[nepi.git] / examples / omf / testing / nepi_omf5_plexus_ccncat_linear.py
1 """
2     NEPI, a framework to manage network experiments
3     Copyright (C) 2013 INRIA
4
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.
9
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.
14
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/>.
17
18     Author: Alina Quereilhac <alina.quereilhac@inria.fr>
19             Julien Tribino <julien.tribino@inria.fr>
20
21     Example :
22       - Testbed : Nitos
23       - Explanation :
24
25       CCN topology:
26     
27                  
28                    
29      content                ccncat        ccncat
30      h1      h2      h3      h4            h5
31      0 ----- 0 ----- 0 ------ 0 ------------0
32                
33
34       - Experiment:
35         * t0 : h4 retrieves the content and we measure the time
36         * t1 : h5 retrieve the content and should go faster than h4
37
38 """
39
40 #!/usr/bin/env python
41 from nepi.execution.resource import ResourceFactory, ResourceAction, ResourceState
42 from nepi.execution.ec import ExperimentController
43
44 from optparse import OptionParser, SUPPRESS_HELP
45
46 ###  Define OMF Method to simplify definition of resources ###
47 def add_node(ec, hostname, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
48     node = ec.register_resource("OMFNode")
49     ec.set(node, 'hostname', hostname)
50     ec.set(node, 'xmppServer', xmppServer)
51     ec.set(node, 'xmppUser', xmppUser)
52     ec.set(node, 'xmppPort', xmppPort)
53     ec.set(node, 'xmppPassword', xmppPassword)
54     ec.set(node, 'version', "5")
55     return node
56
57 def add_interface(ec, ip, xmppServer, xmppUser, essid = "ccn", name = "wlan0", mode = "adhoc",
58                  typ = "g", xmppPort = "5222", xmppPassword = "1234"):
59     iface = ec.register_resource("OMFWifiInterface")
60     ec.set(iface, 'name', name)
61     ec.set(iface, 'mode', mode)
62     ec.set(iface, 'hw_mode', typ)
63     ec.set(iface, 'essid', essid)
64     ec.set(iface, 'ip', ip)
65     ec.set(iface, 'version', "5")
66     return iface
67
68 def add_channel(ec, channel, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
69     chan = ec.register_resource("OMFChannel")
70     ec.set(chan, 'channel', channel)
71     ec.set(chan, 'xmppServer', xmppServer)
72     ec.set(chan, 'xmppUser', xmppUser)
73     ec.set(chan, 'xmppPort', xmppPort)
74     ec.set(chan, 'xmppPassword', xmppPassword)
75     ec.set(chan, 'version', "5")
76     return chan
77
78 def add_app(ec, host,  appid, command, env, xmppServer, xmppUser, 
79                 xmppPort = "5222", xmppPassword = "1234"):
80     app = ec.register_resource("OMFApplication")
81     ec.set(app, 'appid', appid)
82     ec.set(app, 'command', command)
83     ec.set(app, 'env', env)
84     ec.set(app, 'version', "5")
85     ec.register_connection(app, host)
86     return app
87
88
89 ###  Define a CCND application  ###
90 def add_ccnd(ec, host, peers, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
91     env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root \
92 CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"'
93
94     # BASH command -> ' ccndstart ; ccndc add ccnx:/ udp host ; ccnr '
95     command = "ccndc add ccnx:/ udp " + peers
96     app = add_app(ec, host, "#ccnd", command, env, xmppServer, xmppUser,
97                     xmppPort = xmppPort, xmppPassword = xmppPassword)
98     return app
99
100 ###  Define a CCN SeqWriter application ###
101 def add_publish(ec, host,  movie, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
102     env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"'
103
104     # BASH command -> 'ccnseqwriter -r ccnx:/VIDEO < movie'
105     command = "ccnseqwriter -r ccnx:/VIDEO"
106     command += " < " + movie
107
108     app = add_app(ec, host, "#ccn_write", command, env, xmppServer, xmppUser,
109                   xmppPort = xmppPort, xmppPassword = xmppPassword)
110     return app
111
112 ###  Define a streaming application ###
113 def add_stream(ec, host, xmppServer, xmppUser, xmppPort = "5222", xmppPassword = "1234"):
114     env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"'
115     command = " ddbus-uuidgen --ensure ; ( /root/ccnx-0.7.2/bin/ccncat ccnx:/VIDEO | /root/vlc-1.1.13/cvlc - )  "
116     app = add_app(ec, host, "#ccn_stream", command, env, xmppServer, xmppUser,
117                   xmppPort = xmppPort, xmppPassword = xmppPassword)
118     return app
119
120 ###  Many options to easily addapt the script ####
121 def get_options():
122     usage = "usage: %prog -c <channel> -s <xmpp_slice> -x <xmpp_host> -m <movie>"
123
124     parser = OptionParser(usage=usage)
125     parser.add_option("-c", "--channel", dest="channel", 
126             help="Channel of the communication", type="str")
127     parser.add_option("-s", "--xmpp-slice", dest="xmpp_slice", 
128             help="Name of the slice XMPP", type="str")
129     parser.add_option("-x", "--xmpp-host", dest="xmpp_host",
130             help="Name of the host XMPP", type="str")
131     #parser.add_option("-e", "--exp-id", dest="exp_id", 
132     #        help="Label to identify experiment", type="str")
133
134     (options, args) = parser.parse_args()
135
136     return (options.channel, options.xmpp_slice, 
137             options.xmpp_host)
138
139 ### Script itself ###
140 if __name__ == '__main__':
141     (channel, xmpp_slice, xmpp_host) = get_options()
142
143     env = 'PATH=$PATH:/root/ccnx-0.7.2/bin HOME=/root CCNR_DIRECTORY="/root" CCNR_STATUS_PORT="8080"'
144
145 # Create the EC
146     ec = ExperimentController()
147
148 # Create the topology
149     host1 = "omf.plexus.wlab5"
150     host2 = "omf.plexus.wlab9"
151     host3 = "omf.plexus.wlab10"
152     host4 = "omf.plexus.wlab24"
153     host5 = "omf.plexus.wlab29"  # b1
154
155     ip1 = "10.0.0.5/24"
156     ip2 = "10.0.0.9/24"
157     ip3 = "10.0.0.10/24"
158     ip4 = "10.0.0.24/24"
159     ip5 = "10.0.0.29/24"
160
161     all_hosts = [host1, host2, host3, host4, host5]
162     all_ip = [ip1, ip2, ip3, ip4, ip5]
163
164     ring_hosts = [host1, host2, host3, host4]
165     nodes = dict()
166
167     chann = add_channel(ec, channel, xmpp_slice, xmpp_host)
168     for i in xrange(len(all_hosts)):
169         node = add_node(ec,all_hosts[i], xmpp_slice, xmpp_host)
170         iface = add_interface(ec, all_ip[i], xmpp_slice, xmpp_host)
171         ec.register_connection(node, iface)
172         ec.register_connection(iface, chann)
173         nodes[all_hosts[i]] = node
174
175 #### CCN setup for the node
176 ###    ccnds = dict()
177 ###    ccnrs = dict()
178 ###    for i in xrange(len(all_hosts)):
179 ###        ccndstart = add_app(ec, nodes[all_hosts[i]],  "#ccndstart", "ccndstart &", 
180 ###                              env, xmpp_slice, xmpp_host)
181 ###        ccnr = add_app(ec, nodes[all_hosts[i]],  "#ccnr", "ccnr &", 
182 ###                            env, xmpp_slice, xmpp_host)
183 ###        ccnds[all_hosts[i]] = ccndstart
184 ###        ccnrs[all_hosts[i]] = ccnr
185 ###        ec.register_condition(ccnr, ResourceAction.START, ccndstart, ResourceState.STARTED, "1s")
186
187 #### CCNDC setup 
188 ###    # l1 : h1 - h2 , h2 - h1
189 ###    l1u = add_ccnd(ec, nodes[host1], ip2, xmpp_slice, xmpp_host)
190 ###    l1d = add_ccnd(ec, nodes[host2], ip1, xmpp_slice, xmpp_host)
191
192 ###    # l2 : h2 - h3 , h3 - h2
193 ###    l2u = add_ccnd(ec, nodes[host2], ip3, xmpp_slice, xmpp_host)
194 ###    l2d = add_ccnd(ec, nodes[host3], ip2, xmpp_slice, xmpp_host)
195
196 ###    # l3 : h3 - h4 , h4 - h3
197 ###    l3u = add_ccnd(ec, nodes[host3], ip4, xmpp_slice, xmpp_host)
198 ###    l3d = add_ccnd(ec, nodes[host4], ip3, xmpp_slice, xmpp_host)
199
200 ###    # l4 : h4 - h5 , h5 - h4
201 ###    l4u = add_ccnd(ec, nodes[host4], ip5, xmpp_slice, xmpp_host)
202 ###    l4d = add_ccnd(ec, nodes[host5], ip4, xmpp_slice, xmpp_host)
203
204 ###    link = [l1u, l1d, l2u, l2d, l3u, l3d, l4u, l4d]
205
206 #### List of condition
207 ###    for i in xrange(len(all_hosts)):
208 ###         ec.register_condition(ccnrs[all_hosts[i]], ResourceAction.START, ccnds[all_hosts[i]], ResourceState.STARTED, "1s")
209 ###         ec.register_condition(link, ResourceAction.START, ccnrs[all_hosts[i]], ResourceState.STARTED, "1s")
210
211
212 # Do the iperf
213     iperfserv = dict()
214     iperfclient = dict()
215     for i in xrange(len(all_hosts)):
216         perfserv = add_app(ec, nodes[all_hosts[i]],  "#perfserv", "iperf -s > /opt/iperfserv.txt", 
217                               env, xmpp_slice, xmpp_host)
218         iperfclient[all_hosts[i]] = []
219         if i > 0:
220             cmd = "iperf -c " + all_ip[i-1] + " > /opt/iperclient1.txt"
221             perfclient1 = add_app(ec, nodes[all_hosts[i]],  "#perfclient1", cmd, 
222                             env, xmpp_slice, xmpp_host)
223             iperfclient[all_hosts[i]].append(perfclient1)
224
225         if i < (len(all_hosts)-1):
226             cmd = "iperf -c " + all_ip[i+1] + " > /opt/iperclient2.txt"
227             perfclient2 = add_app(ec, nodes[all_hosts[i]],  "#perfclient2", cmd, 
228                             env, xmpp_slice, xmpp_host)
229             iperfclient[all_hosts[i]].append(perfclient2)
230
231         iperfserv[all_hosts[i]] = perfserv
232
233     for i in xrange(len(all_hosts)):
234          #ec.register_condition(iperfserv[all_hosts[i]], ResourceAction.START, link, ResourceState.STARTED, "2s")
235          for elt in iperfclient[all_hosts[i]]:
236              ec.register_condition(elt, ResourceAction.START, iperfserv[all_hosts[i]], ResourceState.STARTED, "3s")
237
238
239 ## Streaming Server
240 #    pub = add_publish(ec, nodes[host5], movie, xmpp_slice, xmpp_host)
241
242 ## Streaming client
243 #    stream = add_stream(ec, nodes[host6], xmpp_slice, xmpp_host)
244
245 ## Streaming conditions
246 #    ec.register_condition(pub, ResourceAction.START, link, ResourceState.STARTED, "2s")
247 #    ec.register_condition(stream, ResourceAction.START, link, ResourceState.STARTED, "2s")
248 #    ec.register_condition(stream, ResourceAction.START, pub, ResourceState.STARTED, "2s")
249
250
251
252 ### Cleanning ###
253 # Cleaning when the experiment stop
254 ##    ccndstops = []
255 ##    for i in xrange(len(all_hosts)):
256 ##        ccndstop = add_app(ec, nodes[all_hosts[i]], "#ccndstop", "ccndstop", env, xmpp_slice, xmpp_host)
257 ##        ccndstops.append(ccndstop)
258     perfkill = dict()
259     for i in xrange(len(all_hosts)):
260         kill = add_app(ec, nodes[all_hosts[i]], "#kill", "killall iperf", "", xmpp_slice, xmpp_host)
261         perfkill[all_hosts[i]] = kill
262
263
264 # Condition to stop and clean the experiment
265     apps = []
266     for i in xrange(len(all_hosts)):
267 #        apps.append(ccnds[all_hosts[i]])
268 #        apps.append(ccnrs[all_hosts[i]])
269         apps.append(iperfserv[all_hosts[i]])
270         for elt in iperfclient[all_hosts[i]]:
271             apps.append(elt)
272 #    apps += link
273     #apps.append(pub)
274     #apps.append(stream)
275
276     ec.register_condition(apps, ResourceAction.STOP, apps, ResourceState.STARTED, "20s")
277
278 #    ec.register_condition(ccndstops + [killall], ResourceAction.START, apps, ResourceState.STOPPED, "1s")
279 #    ec.register_condition(ccndstops + [killall], ResourceAction.STOP, ccndstops, ResourceState.STARTED, "1s")
280
281     killall = []
282     for i in xrange(len(all_hosts)):
283         killall.append(perfkill[all_hosts[i]])
284
285     ec.register_condition(killall, ResourceAction.START, apps, ResourceState.STOPPED, "1s")
286     ec.register_condition(killall, ResourceAction.STOP, killall, ResourceState.STARTED, "1s")
287
288 ### Deploy and Wait ###
289 # Deploy all ResourceManagers
290     ec.deploy()
291
292 # Wait until the applications are finished
293     ec.wait_finished(killall)
294
295 # Shutdown the experiment controller
296     ec.shutdown()
297
298