910b95cdcdff90254e231d9f30993fdbde5eafb2
[nepi.git] / examples / omf / vod_exp / vod_experiment.py
1 #!/usr/bin/env python
2 #
3 #    NEPI, a framework to manage network experiments
4 #    Copyright (C) 2013 INRIA
5 #
6 #    This program is free software: you can redistribute it and/or modify
7 #    it under the terms of the GNU General Public License as published by
8 #    the Free Software Foundation, either version 3 of the License, or
9 #    (at your option) any later version.
10 #
11 #    This program is distributed in the hope that it will be useful,
12 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #    GNU General Public License for more details.
15 #
16 #    You should have received a copy of the GNU General Public License
17 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19
20 from nepi.execution.ec import ExperimentController
21 from nepi.execution.resource import ResourceAction, ResourceState
22
23 import os
24 import time
25 import argparse
26
27 # Set experiment for broadcast or vod mode
28
29 parser = argparse.ArgumentParser(description='NEPI VoD/Broadcast experiment')
30 parser.add_argument('-m', '--mode', help='Set vlc mode, possible values <vod> or <broadcast>', required=True)
31 args = parser.parse_args()
32
33 mode = args.mode
34
35 # Create the entity Experiment Controller
36
37 exp_id = "vod_exp"
38 ec = ExperimentController(exp_id)
39
40 # Define SFA credentials
41
42 slicename = 'ple.inria.nepi'
43 sfauser = 'ple.inria.aquereilhac'
44 sfaPrivateKey = '/home/alina/.sfi/aquereilhac.pkey'
45
46 # Functions for nodes and ifaces registration
47
48 def create_planetlab_node(ec, host):
49     node = ec.register_resource("planetlab::sfa::Node")
50     ec.set(node, "hostname", host)
51     ec.set(node, "username", "inria_nepi")
52     ec.set(node, "sfauser", sfauser)
53     ec.set(node, "sfaPrivateKey", sfaPrivateKey)
54     ec.set(node, 'cleanExperiment', True)
55     return node
56
57 def create_omf_node(ec, host):
58     node = ec.register_resource("wilabt::sfa::Node")
59     ec.set(node, "host", host)
60     ec.set(node, "slicename", slicename)
61     ec.set(node, "sfauser", sfauser)
62     ec.set(node, "sfaPrivateKey", sfaPrivateKey)
63     ec.set(node, "gatewayUser", "nepi")
64     ec.set(node, "gateway", "bastion.test.iminds.be")
65     ec.set(node, "disk_image", 'NepiVlcOMF6Baseline')
66     ec.set(node, 'xmppServer', "xmpp.ilabt.iminds.be")
67     ec.set(node, 'xmppUser', "nepi")
68     ec.set(node, 'xmppPort', "5222")
69     ec.set(node, 'xmppPassword', "1234")
70     return node
71
72 def create_omf_iface(ec, ip, node):
73     iface = ec.register_resource("omf::WifiInterface")
74     ec.set(iface, 'name', 'wlan0')
75     ec.set(iface, 'mode', "adhoc")
76     ec.set(iface, 'hw_mode', "g")
77     ec.set(iface, 'essid', "vlc")
78     ec.set(iface, 'ip', ip)
79     ec.register_connection(iface, node)
80     return iface
81
82 # Register Internet VLC server
83
84 video_server = create_planetlab_node(ec, 'planetlab3.xeno.cl.cam.ac.uk')
85
86 # Register wifi media center and client nodes
87
88 wifi_center = create_omf_node(ec, 'zotacB1')
89 client1 = create_omf_node(ec, 'zotacB3')
90 client2 = create_omf_node(ec, 'zotacB5')
91 client3 = create_omf_node(ec, 'zotacC1')
92 client4 = create_omf_node(ec, 'zotacC3')
93 client5 = create_omf_node(ec, 'zotacB2')
94
95 omf_nodes = [wifi_center, client1, client2, client3, client4, client5]
96
97 # Register ifaces in wireless nodes
98
99 iface_center = create_omf_iface(ec, "192.168.0.1/24", wifi_center)
100 iface_client1 = create_omf_iface(ec, "192.168.0.2/24", client1)
101 iface_client2 = create_omf_iface(ec, "192.168.0.3/24", client2)
102 iface_client3 = create_omf_iface(ec, "192.168.0.4/24", client3)
103 iface_client4 = create_omf_iface(ec, "192.168.0.5/24", client4)
104 iface_client5 = create_omf_iface(ec, "192.168.0.6/24", client5)
105
106 omf_ifaces = [iface_center, iface_client1, iface_client2, iface_client3, iface_client4, iface_client5]
107
108 # Register channel
109
110 chan = ec.register_resource("omf::Channel")
111 ec.set(chan, 'channel', "6")
112
113 # Register connection ifaces - channel
114
115 ec.register_connection(iface_center, chan)
116 ec.register_connection(iface_client1, chan)
117 ec.register_connection(iface_client2, chan)
118 ec.register_connection(iface_client3, chan)
119 ec.register_connection(iface_client4, chan)
120 ec.register_connection(iface_client5, chan)
121
122 resources = [video_server] + omf_nodes + omf_ifaces + [chan]
123
124 # Deploy physical resources and wait until they become provisioned
125
126 ec.deploy(resources)
127
128 ec.wait_deployed(resources)
129   
130 time.sleep(3)
131
132 # Functions for applications registration in the nodes
133
134 def create_vlc_server(ec, video_server, mode):
135     vlc_server = ec.register_resource("linux::Application")
136     ec.set(vlc_server, "depends", "vlc")
137     ec.set(vlc_server, "sources", "examples/omf/demo_openlab/big_buck_bunny_240p_mpeg4_lq.ts")
138     # Depending on the mode selected to run the experiment, 
139     # different configuation files and command to run are
140     # uploaded to the server
141     if mode == 'vod':
142         ec.set(vlc_server, "files", "examples/omf/demo_openlab/conf_VoD.vlm")
143         ec.set(vlc_server, "command", "sudo -S dbus-uuidgen --ensure ; cvlc --vlm-conf ${SHARE}/conf_VoD.vlm --rtsp-host 128.232.103.203:5554 2>/tmp/logpl.txt")
144     elif mode == 'broadcast':
145         ec.set(vlc_server, "files", "examples/omf/demo_openlab/conf_Broadcast.vlm")
146         ec.set(vlc_server, "command", "sudo -S dbus-uuidgen --ensure ; cvlc --vlm-conf ${SHARE}/conf_Broadcast.vlm --rtsp-host 128.232.103.203:5554 2>/tmp/logpl.txt")
147     ec.register_connection(video_server, vlc_server)
148     return vlc_server
149
150 def create_omf_app(ec, command, node):
151     app = ec.register_resource("omf::Application")
152     ec.set(app, 'command', command)
153     ec.register_connection(app, node)
154     return app
155
156
157 # Run the VLC server in the Planetlab node
158
159 vlc_server = create_vlc_server(ec, video_server, mode)
160
161 # Upload configuration to the wifi media center and run VLC
162
163 if mode == 'vod':
164     update_file_wificenter = "echo -e 'new BUNNY vod enabled\\n"\
165        "setup BUNNY input rtsp://128.232.103.203:5554/BUNNY' > /root/wificenter.vlm"
166     command_wificenter =  "/root/vlc/vlc-1.1.13/cvlc --vlm-conf /root/wificenter.vlm --rtsp-host 192.168.0.1:5554"
167 elif mode == 'broadcast':
168     update_file_wificenter = "echo -e 'new BUNNY broadcast enabled loop\\n"\
169        "setup BUNNY input rtsp://128.232.103.203:8554/BUNNY\\n"\
170        "setup BUNNY output #rtp{access=udp,mux=ts,sdp=rtsp://0.0.0.0:8554/BUNNY}\\n\\n"\
171        "new test_sched schedule enabled\\n"\
172        "setup test_sched append control BUNNY play' > /root/wificenter.vlm"
173     command_wificenter =  "/root/vlc/vlc-1.1.13/cvlc --vlm-conf /root/wificenter.vlm --rtsp-host 192.168.0.1:8554"
174
175 upload_conf = create_omf_app(ec, update_file_wificenter , wifi_center)
176 vlc_wificenter = create_omf_app(ec, command_wificenter , wifi_center)
177
178 ec.register_condition(upload_conf, ResourceAction.START, vlc_server, ResourceState.STARTED , "2s")
179 ec.register_condition(vlc_wificenter, ResourceAction.START, upload_conf, ResourceState.STARTED , "2s")
180
181 # measurements in video server (PL node)
182 measure_videoserver = ec.register_resource("linux::Application")
183 ec.set(measure_videoserver, "depends", "tcpdump")
184 ec.set(measure_videoserver, "sudo", True)
185 command = "tcpdump -i eth0 not arp -n -w /tmp/capplserver_%s.pcap" % ("$(date +'%Y%m%d%H%M%S')")
186 ec.set(measure_videoserver, "command", command)
187 ec.register_connection(measure_videoserver, video_server)
188
189 # Deploy servers
190 ec.deploy([vlc_server, upload_conf, vlc_wificenter, measure_videoserver])
191
192 ec.wait_started([vlc_server, upload_conf, vlc_wificenter, measure_videoserver])
193
194 time.sleep(3)
195
196 def deploy_experiment(ec, clients, wifi_center):
197
198     # measurements in transmitter eth0
199     command_measure_wificentereth0 = "/usr/sbin/tcpdump -i eth0 not arp -n -w /tmp/capwificen_eth0_%s_%s.pcap" % (len(clients), "$(date +'%Y%m%d%H%M%S')")
200     measure_wificentereth0 = create_omf_app(ec, command_measure_wificentereth0, wifi_center)
201     ec.register_condition(measure_wificentereth0, ResourceAction.STOP, measure_wificentereth0, ResourceState.STARTED , "65s")
202
203     # measurements in transmitter wlan0
204     command_measure_wificenterwlan0 = "/usr/sbin/tcpdump -i wlan0 not arp -n -w /tmp/capwificen_wlan0_%s_%s.pcap" % (len(clients), "$(date +'%Y%m%d%H%M%S')")
205     measure_wificenterwlan0 = create_omf_app(ec, command_measure_wificenterwlan0, wifi_center)
206     ec.register_condition(measure_wificenterwlan0, ResourceAction.STOP, measure_wificenterwlan0, ResourceState.STARTED , "65s")
207
208     # kill tcpdumps in wificenter
209     command_kill_measure_wificentereth0 = "killall /usr/sbin/tcpdump"
210     kill_measure_wificentereth0 = create_omf_app(ec, command_kill_measure_wificentereth0, wifi_center)
211     ec.register_condition(kill_measure_wificentereth0, ResourceAction.START, measure_wificentereth0, ResourceState.STARTED , "65s")
212     ec.register_condition(kill_measure_wificentereth0, ResourceAction.STOP, kill_measure_wificentereth0, ResourceState.STARTED , "2s")
213
214
215     apps = [measure_wificentereth0, measure_wificenterwlan0, kill_measure_wificentereth0]
216     delay = '2s'
217     for client in clients:
218         client_host = ec.get(client, 'host').split('.')[0]
219         # measurements in clients
220         command_measure_client = "/usr/sbin/tcpdump -i wlan0 not arp -n -w /tmp/capcli_%s_%s_%s.pcap" % (client_host, len(clients), "$(date +'%Y%m%d%H%M%S')")
221         # run vlc client
222         if mode == 'broadcast':
223             command_client =  "/root/vlc/vlc-1.1.13/cvlc rtsp://192.168.0.1:8554/BUNNY --sout=file/ts:%s_%s_%s.ts 2>/tmp/logcli.txt" % (client_host, len(clients), "$(date +'%Y%m%d%H%M%S')")
224         elif mode == 'vod':    
225             command_client =  "/root/vlc/vlc-1.1.13/cvlc rtsp://192.168.0.1:5554/BUNNY --sout=file/ts:%s_%s_%s.ts 2>/tmp/logcli.txt" % (client_host, len(clients), "$(date +'%Y%m%d%H%M%S')")
226
227         # kill vlc client and tcpdump
228         command_client_killvlc = "killall vlc vlc_app"
229         command_client_killtcp = "killall /usr/sbin/tcpdump"
230
231         run_client = create_omf_app(ec, command_client, client)
232         measure_client = create_omf_app(ec, command_measure_client, client)
233         kill_clientvlc = create_omf_app(ec, command_client_killvlc, client)
234         kill_clienttcp = create_omf_app(ec, command_client_killtcp, client)
235         ec.register_condition(run_client, ResourceAction.START, measure_client, ResourceState.STARTED , delay)
236         ec.register_condition([run_client, measure_client], ResourceAction.STOP, run_client, ResourceState.STARTED , "60s")
237         ec.register_condition(kill_clientvlc, ResourceAction.START, run_client, ResourceState.STARTED , "60s")
238         ec.register_condition(kill_clienttcp, ResourceAction.START, measure_client, ResourceState.STARTED , "60s")
239         ec.register_condition(kill_clientvlc, ResourceAction.STOP, kill_clientvlc, ResourceState.STARTED , "2s")
240         ec.register_condition(kill_clienttcp, ResourceAction.STOP, kill_clienttcp, ResourceState.STARTED , "2s")
241         apps.append(run_client)
242         apps.append(measure_client)
243         apps.append(kill_clientvlc)
244         apps.append(kill_clienttcp)
245     
246     return apps
247
248 #################
249 ## 1 client run #
250 #################
251
252 apps1 = deploy_experiment(ec, [client1], wifi_center)
253
254 ec.deploy(apps1)
255 ec.wait_finished(apps1)
256
257 ################
258 # 3 client run #
259 ################
260
261 #apps3 = deploy_experiment(ec, [client1, client2, client3], wifi_center)
262 #
263 #ec.deploy(apps3)
264 #ec.wait_finished(apps3)
265
266 ################
267 # 5 client run #
268 ################
269 #
270 #apps5 = deploy_experiment(ec, [client1, client2, client3, client4, client5], wifi_center)
271
272 #ec.deploy(apps5)
273 #ec.wait_finished(apps5)
274
275 ec.shutdown()
276
277 # End