| 1 | == C. Orchestrate/Run Experiment == |
| 2 | |
| 3 | {{{ |
| 4 | #!html |
| 5 | <div style="text-align:left; width:323px; margin-left:auto; margin-right:auto;"> |
| 6 | <img id="Image-Maps_2201210012154478" src="http://emmy9.casa.umass.edu/images/GIMI_workflow_C.jpg" usemap="#Image-Maps_2201210012154478" border="0" width="323" height="531" alt="" /> |
| 7 | <map id="_Image-Maps_2201210012154478" name="Image-Maps_2201210012154478"> |
| 8 | <area shape="rect" coords="14,16,52,54" href="http://groups.geni.net/geni/wiki/gimiv1.1tutorial/environment" alt="" title="" /> |
| 9 | <area shape="rect" coords="53,10,152,60" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Environment" alt="" title="" /> |
| 10 | <area shape="rect" coords="53,86,152,136" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Slice" alt="" title="" /> |
| 11 | <area shape="rect" coords="53,162,152,212" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Orchestrate" alt="" title="" /> |
| 12 | <area shape="rect" coords="53,237,152,287" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Observe" alt="" title="" /> |
| 13 | <area shape="rect" coords="52,312,151,362" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Toirods" alt="" title="" /> |
| 14 | <area shape="rect" coords="53,387,152,437" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Fromirods" alt="" title="" /> |
| 15 | <area shape="rect" coords="169,388,268,438" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Analyze" alt="" title="" /> |
| 16 | <area shape="rect" coords="53,462,152,512" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Cleanup" alt="" title="" /> |
| 17 | <area shape="rect" coords="12,91,55,128" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Slice" alt="" title="" /> |
| 18 | <area shape="rect" coords="11,167,54,204" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Orchestrate" alt="" title="" /> |
| 19 | <area shape="rect" coords="11,242,54,279" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Observe" alt="" title="" /> |
| 20 | <area shape="rect" coords="9,317,52,354" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Toirods" alt="" title="" /> |
| 21 | <area shape="rect" coords="269,393,312,430" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Analyze" alt="" title="" /> |
| 22 | <area shape="rect" coords="10,391,53,428" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Fromirods" alt="" title="" /> |
| 23 | <area shape="rect" coords="11,467,54,504" href="http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Cleanup" alt="" title="" /> |
| 24 | <area shape="rect" coords="321,529,323,531" href="http://www.image-maps.com/index.php?aff=mapped_users_2201210012154478" alt="Image Map" title="Image Map" /> |
| 25 | </map> |
| 26 | <!-- Image map text links - End - --> |
| 27 | |
| 28 | </div> |
| 29 | }}} |
| 30 | |
| 31 | === C.1 Initial Setup === |
| 32 | |
| 33 | === C.1.1 Starting the OML Server (if needed) === |
| 34 | For this tutorial we have an OML server running on emmy9.casa.umass.edu, which collects the measurement data in an sqlite3 database and at the end of the experiment it pushes the data to IRODS. |
| 35 | * Here is how you would have to start an OML server if you wanted to run this on a different machine (OML2.8 is required.) |
| 36 | {{{ |
| 37 | #!html |
| 38 | <span style="color:red">DO NOT perform this task in the tutorial. |
| 39 | </span> |
| 40 | }}} |
| 41 | |
| 42 | This is explained the [OML installation file]. |
| 43 | |
| 44 | {{{ |
| 45 | $ /usr/bin/oml2-server -l 3003 --logfile=/var/log/oml2-server-2.9.log --user=oml2 --group=oml2 -H /usr/share/oml2-server/oml2-server-hook.sh |
| 46 | }}} |
| 47 | |
| 48 | The latest version of OML offers the capability of executing a script after the measurement has finished. In OML terminology this is called a "hook". The hook script we use is attached at the bottom of this wiki page [http://groups.geni.net/geni/attachment/wiki/GIMIv1.1Tutorial/Orchestrate/oml2-server-hook.sh (oml2-server-hook.sh)]. |
| 49 | |
| 50 | {{{ |
| 51 | List and explain final hook script here! |
| 52 | }}} |
| 53 | |
| 54 | At the [http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/OmlServer following page] we give the interested experimenter additional information on how they can run their own OML server independent of the one offered by GIMI. |
| 55 | |
| 56 | ---- |
| 57 | |
| 58 | === C.1.2 Verification of Topology === |
| 59 | After establishing the slice on which the experiment will be executed, the experimenter will be most likely |
| 60 | be interested in verifying if the slice has been initiated correctly. In this tutorial, we use an [[http://emmy9.casa.umass.edu/GEC15-GIMI-Tutorial/step1-ping_all.rb OMF experiment script]] that executes pings between neighboring nodes. |
| 61 | [[BR]] |
| 62 | The following figure shows that a total of 12 (between each pair of nodes and in each direction) ping are performed. |
| 63 | |
| 64 | [[Image(ping.png)]] |
| 65 | |
| 66 | {{{ |
| 67 | defProperty('source1', "nodeA", "ID of a resource") |
| 68 | defProperty('source2', "nodeB", "ID of a resource") |
| 69 | defProperty('source3', "nodeC", "ID of a resource") |
| 70 | defProperty('source4', "nodeD", "ID of a resource") |
| 71 | defProperty('source5', "nodeE", "ID of a resource") |
| 72 | |
| 73 | #defProperty('sink1', "nodeA", "ID of a sink") |
| 74 | #defProperty('sink2', "nodeB", "ID of a sink") |
| 75 | #defProperty('sink3', "nodeC", "ID of a sink") |
| 76 | #defProperty('sink4', "nodeD", "ID of a sink") |
| 77 | #defProperty('sink5', "nodeE", "ID of a sink") |
| 78 | |
| 79 | defProperty('sinkaddr11', '192.168.4.10', "Ping destination address") |
| 80 | defProperty('sinkaddr12', '192.168.5.12', "Ping destination address") |
| 81 | |
| 82 | defProperty('sinkaddr21', '192.168.4.11', "Ping destination address") |
| 83 | defProperty('sinkaddr22', '192.168.2.12', "Ping destination address") |
| 84 | defProperty('sinkaddr23', '192.168.1.13', "Ping destination address") |
| 85 | |
| 86 | defProperty('sinkaddr31', '192.168.5.11', "Ping destination address") |
| 87 | defProperty('sinkaddr32', '192.168.2.10', "Ping destination address") |
| 88 | defProperty('sinkaddr33', '192.168.3.13', "Ping destination address") |
| 89 | defProperty('sinkaddr34', '192.168.6.14', "Ping destination address") |
| 90 | |
| 91 | defProperty('sinkaddr41', '192.168.1.10', "Ping destination address") |
| 92 | defProperty('sinkaddr42', '192.168.3.12', "Ping destination address") |
| 93 | |
| 94 | defProperty('sinkaddr51', '192.168.6.12', "Ping destination address") |
| 95 | |
| 96 | defApplication('ping_app', 'pingmonitor') do |a| |
| 97 | a.path = "/root/pingWrap.rb" |
| 98 | a.version(1, 2, 0) |
| 99 | a.shortDescription = "Wrapper around ping" |
| 100 | a.description = "ping application" |
| 101 | a.defProperty('dest_addr', 'Address to ping', '-a', {:type => :string, :dynamic => false}) |
| 102 | a.defProperty('count', 'Number of times to ping', '-c', {:type => :integer, :dynamic => false}) |
| 103 | a.defProperty('interval', 'Interval between pings in s', '-i', {:type => :integer, :dynamic => false}) |
| 104 | |
| 105 | a.defMeasurement('myping') do |m| |
| 106 | m.defMetric('dest_addr',:string) |
| 107 | m.defMetric('ttl',:int) |
| 108 | m.defMetric('rtt',:float) |
| 109 | m.defMetric('rtt_unit',:string) |
| 110 | end |
| 111 | end |
| 112 | |
| 113 | defGroup('Source1', property.source1) do |node| |
| 114 | node.addApplication("ping_app") do |app| |
| 115 | app.setProperty('dest_addr', property.sinkaddr11) |
| 116 | app.setProperty('count', 30) |
| 117 | app.setProperty('interval', 1) |
| 118 | app.measure('myping', :samples => 1) |
| 119 | end |
| 120 | |
| 121 | node.addApplication("ping_app") do |app| |
| 122 | app.setProperty('dest_addr', property.sinkaddr12) |
| 123 | app.setProperty('count', 30) |
| 124 | app.setProperty('interval', 1) |
| 125 | app.measure('myping', :samples => 1) |
| 126 | end |
| 127 | end |
| 128 | |
| 129 | defGroup('Source2', property.source2) do |node| |
| 130 | node.addApplication("ping_app") do |app| |
| 131 | app.setProperty('dest_addr', property.sinkaddr21) |
| 132 | app.setProperty('count', 30) |
| 133 | app.setProperty('interval', 1) |
| 134 | app.measure('myping', :samples => 1) |
| 135 | end |
| 136 | |
| 137 | node.addApplication("ping_app") do |app| |
| 138 | app.setProperty('dest_addr', property.sinkaddr22) |
| 139 | app.setProperty('count', 30) |
| 140 | app.setProperty('interval', 1) |
| 141 | app.measure('myping', :samples => 1) |
| 142 | end |
| 143 | |
| 144 | node.addApplication("ping_app") do |app| |
| 145 | app.setProperty('dest_addr', property.sinkaddr23) |
| 146 | app.setProperty('count', 30) |
| 147 | app.setProperty('interval', 1) |
| 148 | app.measure('myping', :samples => 1) |
| 149 | end |
| 150 | end |
| 151 | |
| 152 | defGroup('Source3', property.source3) do |node| |
| 153 | node.addApplication("ping_app") do |app| |
| 154 | app.setProperty('dest_addr', property.sinkaddr31) |
| 155 | app.setProperty('count', 30) |
| 156 | app.setProperty('interval', 1) |
| 157 | app.measure('myping', :samples => 1) |
| 158 | end |
| 159 | |
| 160 | node.addApplication("ping_app") do |app| |
| 161 | app.setProperty('dest_addr', property.sinkaddr32) |
| 162 | app.setProperty('count', 30) |
| 163 | app.setProperty('interval', 1) |
| 164 | app.measure('myping', :samples => 1) |
| 165 | end |
| 166 | |
| 167 | node.addApplication("ping_app") do |app| |
| 168 | app.setProperty('dest_addr', property.sinkaddr33) |
| 169 | app.setProperty('count', 30) |
| 170 | app.setProperty('interval', 1) |
| 171 | app.measure('myping', :samples => 1) |
| 172 | end |
| 173 | |
| 174 | node.addApplication("ping_app") do |app| |
| 175 | app.setProperty('dest_addr', property.sinkaddr34) |
| 176 | app.setProperty('count', 30) |
| 177 | app.setProperty('interval', 1) |
| 178 | app.measure('myping', :samples => 1) |
| 179 | end |
| 180 | end |
| 181 | |
| 182 | defGroup('Source4', property.source4) do |node| |
| 183 | |
| 184 | node.addApplication("ping_app") do |app| |
| 185 | app.setProperty('dest_addr', property.sinkaddr41) |
| 186 | app.setProperty('count', 30) |
| 187 | app.setProperty('interval', 1) |
| 188 | app.measure('myping', :samples => 1) |
| 189 | end |
| 190 | |
| 191 | node.addApplication("ping_app") do |app| |
| 192 | app.setProperty('dest_addr', property.sinkaddr42) |
| 193 | app.setProperty('count', 30) |
| 194 | app.setProperty('interval', 1) |
| 195 | app.measure('myping', :samples => 1) |
| 196 | end |
| 197 | end |
| 198 | |
| 199 | defGroup('Source5', property.source5) do |node| |
| 200 | node.addApplication("ping_app") do |app| |
| 201 | app.setProperty('dest_addr', property.sinkaddr51) |
| 202 | app.setProperty('count', 30) |
| 203 | app.setProperty('interval', 1) |
| 204 | app.measure('myping', :samples => 1) |
| 205 | end |
| 206 | end |
| 207 | |
| 208 | onEvent(:ALL_UP_AND_INSTALLED) do |event| |
| 209 | info "Starting the ping" |
| 210 | allGroups.startApplications |
| 211 | wait 5 |
| 212 | info "Stopping the ping" |
| 213 | allGroups.stopApplications |
| 214 | Experiment.done |
| 215 | end |
| 216 | }}} |
| 217 | |
| 218 | The script is executed from the user workspace as follows: |
| 219 | |
| 220 | {{{ |
| 221 | $ cd ~/Tutorials/GIMI/common/ |
| 222 | $ omf-5.4 exec --no-am -e gimiXX-ping_all -S gimiXX step1-ping_all.rb |
| 223 | }}} |
| 224 | |
| 225 | Where gimiXX has to be replaced by the slice name you are using for your experiment. |
| 226 | |
| 227 | You should see the following output after executing the omf command. |
| 228 | |
| 229 | {{{ |
| 230 | INFO NodeHandler: OMF Experiment Controller 5.4 (git e0eefcf) |
| 231 | INFO NodeHandler: Slice ID: gimi20 |
| 232 | INFO NodeHandler: Experiment ID: gimi20-2012-10-18t14.03.42-04.00 |
| 233 | INFO NodeHandler: Message authentication is disabled |
| 234 | WARN NodeHandler: AM support disabled - any service calls will fail! |
| 235 | INFO Experiment: load system:exp:stdlib |
| 236 | INFO property.resetDelay: resetDelay = 210 (Fixnum) |
| 237 | INFO property.resetTries: resetTries = 1 (Fixnum) |
| 238 | INFO Experiment: load system:exp:eventlib |
| 239 | INFO Experiment: load ping_all.rb |
| 240 | INFO property.source1: source1 = "nodeA" (String) |
| 241 | INFO property.source2: source2 = "nodeB" (String) |
| 242 | INFO property.source3: source3 = "nodeC" (String) |
| 243 | INFO property.source4: source4 = "nodeD" (String) |
| 244 | INFO property.source5: source5 = "nodeE" (String) |
| 245 | INFO property.sinkaddr11: sinkaddr11 = "192.168.4.10" (String) |
| 246 | INFO property.sinkaddr12: sinkaddr12 = "192.168.5.12" (String) |
| 247 | INFO property.sinkaddr21: sinkaddr21 = "192.168.4.11" (String) |
| 248 | INFO property.sinkaddr22: sinkaddr22 = "192.168.2.12" (String) |
| 249 | INFO property.sinkaddr23: sinkaddr23 = "192.168.1.13" (String) |
| 250 | INFO property.sinkaddr31: sinkaddr31 = "192.168.5.11" (String) |
| 251 | INFO property.sinkaddr32: sinkaddr32 = "192.168.2.10" (String) |
| 252 | INFO property.sinkaddr33: sinkaddr33 = "192.168.3.13" (String) |
| 253 | INFO property.sinkaddr34: sinkaddr34 = "192.168.6.14" (String) |
| 254 | INFO property.sinkaddr41: sinkaddr41 = "192.168.1.10" (String) |
| 255 | INFO property.sinkaddr42: sinkaddr42 = "192.168.3.12" (String) |
| 256 | INFO property.sinkaddr51: sinkaddr51 = "192.168.6.12" (String) |
| 257 | INFO Topology: Loading topology 'nodeA'. |
| 258 | INFO Topology: Loading topology 'nodeB'. |
| 259 | INFO Topology: Loading topology 'nodeC'. |
| 260 | INFO Topology: Loading topology 'nodeD'. |
| 261 | INFO Topology: Loading topology 'nodeE'. |
| 262 | INFO Experiment: Switching ON resources which are OFF |
| 263 | INFO ALL_UP_AND_INSTALLED: Event triggered. Starting the associated tasks. |
| 264 | INFO exp: Starting the ping |
| 265 | INFO exp: Request from Experiment Script: Wait for 5s.... |
| 266 | INFO exp: Stopping the ping |
| 267 | INFO EXPERIMENT_DONE: Event triggered. Starting the associated tasks. |
| 268 | INFO NodeHandler: |
| 269 | INFO NodeHandler: Shutting down experiment, please wait... |
| 270 | INFO NodeHandler: |
| 271 | INFO run: Experiment gimi20-2012-10-18t14.03.42-04.00 finished after 0:16 |
| 272 | }}} |
| 273 | |
| 274 | ---- |
| 275 | |
| 276 | === C.1.3 Setup Routing in Experiment Topology === |
| 277 | In more complex topologies routing has to be set up. In our case, this is achieved with the aid of an [[http://emmy9.casa.umass.edu/GEC15-GIMI-Tutorial/step2-routing.rb OMF experiment script]]. The one we use for this tutorial is shown below. |
| 278 | |
| 279 | {{{ |
| 280 | defGroup('Node1', "nodeA") |
| 281 | defGroup('Node2', "nodeB") |
| 282 | defGroup('Node3', "nodeC") |
| 283 | defGroup('Node4', "nodeD") |
| 284 | defGroup('Node5', "nodeE") |
| 285 | |
| 286 | |
| 287 | onEvent(:ALL_UP) do |event| |
| 288 | wait 1 |
| 289 | info 'Changing routing setup' |
| 290 | |
| 291 | group('Node1').exec("route add -net 192.168.1.0/24 gw 192.168.4.10") |
| 292 | group('Node1').exec("route add -net 192.168.2.0/24 gw 192.168.4.10") |
| 293 | group('Node1').exec("route add -net 192.168.3.0/24 gw 192.168.5.12") |
| 294 | group('Node1').exec("route add -net 192.168.6.0/24 gw 192.168.5.12") |
| 295 | group('Node1').exec("echo 1 > /proc/sys/net/ipv4/ip_forward") |
| 296 | |
| 297 | group('Node2').exec("route add -net 192.168.3.0/24 gw 192.168.1.13") |
| 298 | group('Node2').exec("route add -net 192.168.5.0/24 gw 192.168.4.11") |
| 299 | group('Node2').exec("route add -net 192.168.6.0/24 gw 192.168.2.12") |
| 300 | group('Node2').exec("echo 1 > /proc/sys/net/ipv4/ip_forward") |
| 301 | |
| 302 | group('Node3').exec("route add -net 192.168.1.0/24 gw 192.168.3.13") |
| 303 | group('Node3').exec("route add -net 192.168.4.0/24 gw 192.168.5.11") |
| 304 | group('Node3').exec("echo 1 > /proc/sys/net/ipv4/ip_forward") |
| 305 | |
| 306 | group('Node4').exec("route add -net 192.168.2.0/24 gw 192.168.3.12") |
| 307 | group('Node4').exec("route add -net 192.168.4.0/24 gw 192.168.1.10") |
| 308 | group('Node4').exec("route add -net 192.168.5.0/24 gw 192.168.3.12") |
| 309 | group('Node4').exec("route add -net 192.168.6.0/24 gw 192.168.3.12") |
| 310 | group('Node4').exec("echo 1 > /proc/sys/net/ipv4/ip_forward") |
| 311 | |
| 312 | group('Node5').exec("route add -net 192.168.2.0/24 gw 192.168.6.12") |
| 313 | group('Node5').exec("route add -net 192.168.1.0/24 gw 192.168.6.12") |
| 314 | group('Node5').exec("route add -net 192.168.3.0/24 gw 192.168.6.12") |
| 315 | group('Node5').exec("route add -net 192.168.4.0/24 gw 192.168.6.12") |
| 316 | group('Node5').exec("route add -net 192.168.5.0/24 gw 192.168.6.12") |
| 317 | |
| 318 | info 'Routing setup finished' |
| 319 | wait 5 |
| 320 | info 'Stopping applications' |
| 321 | allGroups.stopApplications |
| 322 | wait 1 |
| 323 | Experiment.done |
| 324 | end |
| 325 | }}} |
| 326 | |
| 327 | This script can be easily adapted if the experimenter wishes to set up the routing between the nodes |
| 328 | differently. |
| 329 | |
| 330 | The script is executed from the user workspace as follows: |
| 331 | |
| 332 | {{{ |
| 333 | $ cd ~/Tutorials/GIMI/common/ |
| 334 | $ omf-5.4 exec --no-am -e gimiXX-routing -S gimiXX step2-routing.rb |
| 335 | }}} |
| 336 | |
| 337 | Where gimiXX has to be replaced by the slice name you are using for your experiment. |
| 338 | |
| 339 | You should see the following output after executing the omf command. |
| 340 | |
| 341 | {{{ |
| 342 | INFO NodeHandler: OMF Experiment Controller 5.4 (git e0eefcf) |
| 343 | INFO NodeHandler: Slice ID: gimi20 |
| 344 | INFO NodeHandler: Experiment ID: gimi20-2012-10-18t14.14.10-04.00 |
| 345 | INFO NodeHandler: Message authentication is disabled |
| 346 | WARN NodeHandler: AM support disabled - any service calls will fail! |
| 347 | INFO Experiment: load system:exp:stdlib |
| 348 | INFO property.resetDelay: resetDelay = 210 (Fixnum) |
| 349 | INFO property.resetTries: resetTries = 1 (Fixnum) |
| 350 | INFO Experiment: load system:exp:eventlib |
| 351 | INFO Experiment: load routing.rb |
| 352 | INFO Topology: Loading topology 'nodeA'. |
| 353 | INFO Topology: Loading topology 'nodeB'. |
| 354 | INFO Topology: Loading topology 'nodeC'. |
| 355 | INFO Topology: Loading topology 'nodeD'. |
| 356 | INFO Topology: Loading topology 'nodeE'. |
| 357 | INFO Experiment: Switching ON resources which are OFF |
| 358 | INFO ALL_UP: Event triggered. Starting the associated tasks. |
| 359 | INFO exp: Request from Experiment Script: Wait for 1s.... |
| 360 | INFO exp: Changing routing setup |
| 361 | INFO exp: Routing setup finished |
| 362 | INFO exp: Request from Experiment Script: Wait for 5s.... |
| 363 | INFO exp: Stopping applications |
| 364 | INFO exp: Request from Experiment Script: Wait for 1s.... |
| 365 | INFO EXPERIMENT_DONE: Event triggered. Starting the associated tasks. |
| 366 | INFO NodeHandler: |
| 367 | INFO NodeHandler: Shutting down experiment, please wait... |
| 368 | INFO NodeHandler: |
| 369 | INFO run: Experiment gimi20-2012-10-18t14.14.10-04.00 finished after 0:16 |
| 370 | }}} |
| 371 | |
| 372 | ---- |
| 373 | |
| 374 | === C.1.4 Verification of Routing === |
| 375 | After establishing the routing, we use an [[http://emmy9.casa.umass.edu/GEC15-GIMI-Tutorial/step3-ping_e2e.rb OMF experiment script]] that executes pings between each pair of nodes that contains one hop, to verify the correctness of routing setup. |
| 376 | |
| 377 | [[Image(GIMIPing_e2e.png)]] |
| 378 | |
| 379 | {{{ |
| 380 | defProperty('source1', "nodeA", "ID of a resource") |
| 381 | defProperty('source2', "nodeB", "ID of a resource") |
| 382 | defProperty('source3', "nodeC", "ID of a resource") |
| 383 | defProperty('source4', "nodeD", "ID of a resource") |
| 384 | defProperty('source5', "nodeE", "ID of a resource") |
| 385 | |
| 386 | defProperty('sinkaddr11', '192.168.1.13', "Ping destination address") |
| 387 | defProperty('sinkaddr12', '192.168.3.13', "Ping destination address") |
| 388 | defProperty('sinkaddr13', '192.168.6.14', "Ping destination address") |
| 389 | |
| 390 | defProperty('sinkaddr21', '192.168.6.14', "Ping destination address") |
| 391 | |
| 392 | defProperty('sinkaddr41', '192.168.4.11', "Ping destination address") |
| 393 | defProperty('sinkaddr42', '192.168.5.11', "Ping destination address") |
| 394 | defProperty('sinkaddr43', '192.168.6.14', "Ping destination address") |
| 395 | |
| 396 | defProperty('sinkaddr51', '192.168.5.11', "Ping destination address") |
| 397 | defProperty('sinkaddr52', '192.168.2.10', "Ping destination address") |
| 398 | defProperty('sinkaddr53', '192.168.3.13', "Ping destination address") |
| 399 | |
| 400 | defApplication('ping_app', 'pingmonitor') do |a| |
| 401 | a.path = "/root/pingWrap.rb" |
| 402 | a.version(1, 2, 0) |
| 403 | a.shortDescription = "Wrapper around ping" |
| 404 | a.description = "ping application" |
| 405 | a.defProperty('dest_addr', 'Address to ping', '-a', {:type => :string, :dynamic => false}) |
| 406 | a.defProperty('count', 'Number of times to ping', '-c', {:type => :integer, :dynamic => false}) |
| 407 | a.defProperty('interval', 'Interval between pings in s', '-i', {:type => :integer, :dynamic => false}) |
| 408 | |
| 409 | a.defMeasurement('myping') do |m| |
| 410 | m.defMetric('dest_addr',:string) |
| 411 | m.defMetric('ttl',:int) |
| 412 | m.defMetric('rtt',:float) |
| 413 | m.defMetric('rtt_unit',:string) |
| 414 | end |
| 415 | end |
| 416 | |
| 417 | defGroup('Source1', property.source1) do |node| |
| 418 | node.addApplication("ping_app") do |app| |
| 419 | app.setProperty('dest_addr', property.sinkaddr11) |
| 420 | app.setProperty('count', 30) |
| 421 | app.setProperty('interval', 1) |
| 422 | app.measure('myping', :samples => 1) |
| 423 | end |
| 424 | |
| 425 | node.addApplication("ping_app") do |app| |
| 426 | app.setProperty('dest_addr', property.sinkaddr12) |
| 427 | app.setProperty('count', 30) |
| 428 | app.setProperty('interval', 1) |
| 429 | app.measure('myping', :samples => 1) |
| 430 | end |
| 431 | |
| 432 | node.addApplication("ping_app") do |app| |
| 433 | app.setProperty('dest_addr', property.sinkaddr13) |
| 434 | app.setProperty('count', 30) |
| 435 | app.setProperty('interval', 1) |
| 436 | app.measure('myping', :samples => 1) |
| 437 | end |
| 438 | end |
| 439 | |
| 440 | defGroup('Source2', property.source1) do |node| |
| 441 | node.addApplication("ping_app") do |app| |
| 442 | app.setProperty('dest_addr', property.sinkaddr21) |
| 443 | app.setProperty('count', 30) |
| 444 | app.setProperty('interval', 1) |
| 445 | app.measure('myping', :samples => 1) |
| 446 | end |
| 447 | end |
| 448 | |
| 449 | defGroup('Source4', property.source3) do |node| |
| 450 | node.addApplication("ping_app") do |app| |
| 451 | app.setProperty('dest_addr', property.sinkaddr41) |
| 452 | app.setProperty('count', 30) |
| 453 | app.setProperty('interval', 1) |
| 454 | app.measure('myping', :samples => 1) |
| 455 | end |
| 456 | |
| 457 | node.addApplication("ping_app") do |app| |
| 458 | app.setProperty('dest_addr', property.sinkaddr42) |
| 459 | app.setProperty('count', 30) |
| 460 | app.setProperty('interval', 1) |
| 461 | app.measure('myping', :samples => 1) |
| 462 | end |
| 463 | |
| 464 | node.addApplication("ping_app") do |app| |
| 465 | app.setProperty('dest_addr', property.sinkaddr43) |
| 466 | app.setProperty('count', 30) |
| 467 | app.setProperty('interval', 1) |
| 468 | app.measure('myping', :samples => 1) |
| 469 | end |
| 470 | end |
| 471 | |
| 472 | defGroup('Source5', property.source3) do |node| |
| 473 | node.addApplication("ping_app") do |app| |
| 474 | app.setProperty('dest_addr', property.sinkaddr51) |
| 475 | app.setProperty('count', 30) |
| 476 | app.setProperty('interval', 1) |
| 477 | app.measure('myping', :samples => 1) |
| 478 | end |
| 479 | |
| 480 | node.addApplication("ping_app") do |app| |
| 481 | app.setProperty('dest_addr', property.sinkaddr52) |
| 482 | app.setProperty('count', 30) |
| 483 | app.setProperty('interval', 1) |
| 484 | app.measure('myping', :samples => 1) |
| 485 | end |
| 486 | |
| 487 | node.addApplication("ping_app") do |app| |
| 488 | app.setProperty('dest_addr', property.sinkaddr53) |
| 489 | app.setProperty('count', 30) |
| 490 | app.setProperty('interval', 1) |
| 491 | app.measure('myping', :samples => 1) |
| 492 | end |
| 493 | end |
| 494 | |
| 495 | onEvent(:ALL_UP_AND_INSTALLED) do |event| |
| 496 | info "Starting the ping" |
| 497 | allGroups.startApplications |
| 498 | wait 5 |
| 499 | info "Stopping the ping" |
| 500 | allGroups.stopApplications |
| 501 | Experiment.done |
| 502 | end |
| 503 | }}} |
| 504 | |
| 505 | The script is executed from the user workspace as follows: |
| 506 | |
| 507 | {{{ |
| 508 | $ cd ~/Tutorials/GIMI/common/ |
| 509 | $ omf-5.4 exec --no-am -e gimiXX-ping_e2e -S gimiXX step3-ping_e2e.rb |
| 510 | }}} |
| 511 | |
| 512 | Where gimiXX has to be replaced by the slice name you are using for your experiment. |
| 513 | |
| 514 | You should see the following output after executing the omf command. |
| 515 | |
| 516 | {{{ |
| 517 | INFO NodeHandler: OMF Experiment Controller 5.4 (git e0eefcf) |
| 518 | INFO NodeHandler: Slice ID: gimi20 |
| 519 | INFO NodeHandler: Experiment ID: gimi20-2012-10-18t14.03.42-04.00 |
| 520 | INFO NodeHandler: Message authentication is disabled |
| 521 | WARN NodeHandler: AM support disabled - any service calls will fail! |
| 522 | INFO Experiment: load system:exp:stdlib |
| 523 | INFO property.resetDelay: resetDelay = 210 (Fixnum) |
| 524 | INFO property.resetTries: resetTries = 1 (Fixnum) |
| 525 | INFO Experiment: load system:exp:eventlib |
| 526 | INFO Experiment: load ping_all.rb |
| 527 | INFO property.source1: source1 = "nodeA" (String) |
| 528 | INFO property.source2: source2 = "nodeB" (String) |
| 529 | INFO property.source3: source3 = "nodeC" (String) |
| 530 | INFO property.source4: source4 = "nodeD" (String) |
| 531 | INFO property.source5: source5 = "nodeE" (String) |
| 532 | INFO property.sinkaddr11: sinkaddr11 = "192.168.4.10" (String) |
| 533 | INFO property.sinkaddr12: sinkaddr12 = "192.168.5.12" (String) |
| 534 | INFO property.sinkaddr21: sinkaddr21 = "192.168.4.11" (String) |
| 535 | INFO property.sinkaddr22: sinkaddr22 = "192.168.2.12" (String) |
| 536 | INFO property.sinkaddr23: sinkaddr23 = "192.168.1.13" (String) |
| 537 | INFO property.sinkaddr31: sinkaddr31 = "192.168.5.11" (String) |
| 538 | INFO property.sinkaddr32: sinkaddr32 = "192.168.2.10" (String) |
| 539 | INFO property.sinkaddr33: sinkaddr33 = "192.168.3.13" (String) |
| 540 | INFO property.sinkaddr34: sinkaddr34 = "192.168.6.14" (String) |
| 541 | INFO property.sinkaddr41: sinkaddr41 = "192.168.1.10" (String) |
| 542 | INFO property.sinkaddr42: sinkaddr42 = "192.168.3.12" (String) |
| 543 | INFO property.sinkaddr51: sinkaddr51 = "192.168.6.12" (String) |
| 544 | INFO Topology: Loading topology 'nodeA'. |
| 545 | INFO Topology: Loading topology 'nodeB'. |
| 546 | INFO Topology: Loading topology 'nodeC'. |
| 547 | INFO Topology: Loading topology 'nodeD'. |
| 548 | INFO Topology: Loading topology 'nodeE'. |
| 549 | INFO Experiment: Switching ON resources which are OFF |
| 550 | INFO ALL_UP_AND_INSTALLED: Event triggered. Starting the associated tasks. |
| 551 | INFO exp: Starting the ping |
| 552 | INFO exp: Request from Experiment Script: Wait for 5s.... |
| 553 | INFO exp: Stopping the ping |
| 554 | INFO EXPERIMENT_DONE: Event triggered. Starting the associated tasks. |
| 555 | INFO NodeHandler: |
| 556 | INFO NodeHandler: Shutting down experiment, please wait... |
| 557 | INFO NodeHandler: |
| 558 | INFO run: Experiment gimi20-2012-10-18t14.03.42-04.00 finished after 0:16 |
| 559 | }}} |
| 560 | |
| 561 | ---- |
| 562 | |
| 563 | === C.2 Running Actual Experiment === |
| 564 | |
| 565 | We will use an [[http://emmy9.casa.umass.edu/GEC15-GIMI-Tutorial/step4-otg_nmetrics.rb OMF experiment script]] to execute oml enabled traffic generator and receiver (otg and otr) to simulate network traffic, and use oml enabled nmetrics to measure the system usage (e.g., CUP, memory) and network interface usage on each of the participated ExoGENI nodes. |
| 566 | |
| 567 | [[Image(otg_nmetrics.png)]] |
| 568 | |
| 569 | |
| 570 | |
| 571 | The one we use for this tutorial is shown below. |
| 572 | |
| 573 | {{{ |
| 574 | defProperty('theSender','nodeB','ID of sender node') |
| 575 | defProperty('theReceiver1', 'nodeE', "ID of receiver node") |
| 576 | defProperty('theReceiver2', 'nodeA', "ID of receiver node") |
| 577 | defProperty('theReceiver3', 'nodeD', "ID of receiver node") |
| 578 | defProperty('packetsize', 128, "Packet size (byte) from the sender node") |
| 579 | defProperty('bitrate', 2048, "Bitrate (bit/s) from the sender node") |
| 580 | defProperty('runtime', 40, "Time in second for the experiment is to run") |
| 581 | |
| 582 | defGroup('Sender',property.theSender) do |node| |
| 583 | options = { 'sample-interval' => 2 } |
| 584 | node.addPrototype("system_monitor", options) |
| 585 | node.addApplication("test:app:otg2") do |app| |
| 586 | app.setProperty('udp:local_host', '192.168.2.10') |
| 587 | app.setProperty('udp:dst_host', '192.168.6.14') |
| 588 | app.setProperty('udp:dst_port', 3000) |
| 589 | app.setProperty('cbr:size', property.packetsize) |
| 590 | app.setProperty('cbr:rate', property.bitrate * 2) |
| 591 | app.measure('udp_out', :samples => 1) |
| 592 | end |
| 593 | |
| 594 | node.addApplication("test:app:otg2") do |app| |
| 595 | app.setProperty('udp:local_host', '192.168.4.10') |
| 596 | app.setProperty('udp:dst_host', '192.168.4.11') |
| 597 | app.setProperty('udp:dst_port', 3000) |
| 598 | app.setProperty('cbr:size', property.packetsize) |
| 599 | app.setProperty('cbr:rate', property.bitrate * 2) |
| 600 | app.measure('udp_out', :samples => 1) |
| 601 | end |
| 602 | |
| 603 | node.addApplication("test:app:otg2") do |app| |
| 604 | app.setProperty('udp:local_host', '192.168.1.10') |
| 605 | app.setProperty('udp:dst_host', '192.168.1.13') |
| 606 | app.setProperty('udp:dst_port', 3000) |
| 607 | app.setProperty('cbr:size', property.packetsize) |
| 608 | app.setProperty('cbr:rate', property.bitrate * 2) |
| 609 | app.measure('udp_out', :samples => 1) |
| 610 | end |
| 611 | end |
| 612 | |
| 613 | defGroup('Receiver1',property.theReceiver1) do |node| |
| 614 | options = { 'sample-interval' => 2 } |
| 615 | node.addPrototype("system_monitor", options) |
| 616 | |
| 617 | node.addApplication("test:app:otr2") do |app| |
| 618 | app.setProperty('udp:local_host', '192.168.6.14') |
| 619 | app.setProperty('udp:local_port', 3000) |
| 620 | app.measure('udp_in', :samples => 1) |
| 621 | end |
| 622 | end |
| 623 | |
| 624 | defGroup('Receiver2',property.theReceiver2) do |node| |
| 625 | options = { 'sample-interval' => 2 } |
| 626 | node.addPrototype("system_monitor", options) |
| 627 | node.addApplication("test:app:otr2") do |app| |
| 628 | app.setProperty('udp:local_host', '192.168.4.11') |
| 629 | app.setProperty('udp:local_port', 3000) |
| 630 | app.measure('udp_in', :samples => 1) |
| 631 | end |
| 632 | end |
| 633 | |
| 634 | defGroup('Receiver3',property.theReceiver3) do |node| |
| 635 | options = { 'sample-interval' => 2 } |
| 636 | node.addPrototype("system_monitor", options) |
| 637 | node.addApplication("test:app:otr2") do |app| |
| 638 | app.setProperty('udp:local_host', '192.168.1.13') |
| 639 | app.setProperty('udp:local_port', 3000) |
| 640 | app.measure('udp_in', :samples => 1) |
| 641 | end |
| 642 | end |
| 643 | |
| 644 | onEvent(:ALL_UP_AND_INSTALLED) do |event| |
| 645 | info "starting" |
| 646 | wait 5 |
| 647 | allGroups.exec("ln -s /usr/local/bin/otr2 /usr/bin/otr2") |
| 648 | allGroups.exec("ln -s /usr/local/bin/otg2 /usr/bin/otg2") |
| 649 | allGroups.exec("ln -s /usr/local/bin/oml2-nmetrics /usr/bin/oml2-nmetrics") |
| 650 | allGroups.startApplications |
| 651 | info "All applications started..." |
| 652 | wait property.runtime / 4 |
| 653 | property.packetsize = 256 |
| 654 | wait property.runtime / 4 |
| 655 | property.packetsize = 512 |
| 656 | wait property.runtime / 4 |
| 657 | property.packetsize = 1024 |
| 658 | wait property.runtime / 4 |
| 659 | allGroups.stopApplications |
| 660 | info "All applications stopped." |
| 661 | Experiment.done |
| 662 | end |
| 663 | }}} |
| 664 | |
| 665 | The script is executed from the user workspace as follows: |
| 666 | |
| 667 | {{{ |
| 668 | $ cd ~/Tutorials/GIMI/common/ |
| 669 | $ omf-5.4 exec --no-am -e gimiXX-otg_nmetrics -S gimiXX step4-otg_nmetrics.rb |
| 670 | }}} |
| 671 | |
| 672 | Where gimiXX has to be replaced by the slice name you are using for your experiment. |
| 673 | |
| 674 | You should see the following output (or similar) after executing the omf command. |
| 675 | |
| 676 | {{{ |
| 677 | INFO NodeHandler: OMF Experiment Controller 5.4 (git e0eefcf) |
| 678 | INFO NodeHandler: Slice ID: gimi20 |
| 679 | INFO NodeHandler: Experiment ID: gimi20-2012-10-18t13.51.41-04.00 |
| 680 | INFO NodeHandler: Message authentication is disabled |
| 681 | WARN NodeHandler: AM support disabled - any service calls will fail! |
| 682 | INFO Experiment: load system:exp:stdlib |
| 683 | INFO property.resetDelay: resetDelay = 210 (Fixnum) |
| 684 | INFO property.resetTries: resetTries = 1 (Fixnum) |
| 685 | INFO Experiment: load system:exp:eventlib |
| 686 | INFO Experiment: load otg_nmetrics.rb |
| 687 | INFO property.theSender: theSender = "nodeB" (String) |
| 688 | INFO property.theReceiver1: theReceiver1 = "nodeE" (String) |
| 689 | INFO property.theReceiver2: theReceiver2 = "nodeA" (String) |
| 690 | INFO property.theReceiver3: theReceiver3 = "nodeD" (String) |
| 691 | INFO property.packetsize: packetsize = 128 (Fixnum) |
| 692 | INFO property.bitrate: bitrate = 2048 (Fixnum) |
| 693 | INFO property.runtime: runtime = 40 (Fixnum) |
| 694 | INFO Topology: Loading topology 'nodeB'. |
| 695 | INFO Topology: Loading topology 'nodeE'. |
| 696 | INFO Topology: Loading topology 'nodeA'. |
| 697 | INFO Topology: Loading topology 'nodeD'. |
| 698 | INFO Experiment: Switching ON resources which are OFF |
| 699 | INFO ALL_UP_AND_INSTALLED: Event triggered. Starting the associated tasks. |
| 700 | INFO exp: starting |
| 701 | INFO exp: Request from Experiment Script: Wait for 5s.... |
| 702 | INFO exp: All applications started... |
| 703 | INFO exp: Request from Experiment Script: Wait for 10s.... |
| 704 | INFO property.packetsize: packetsize = 256 (Fixnum) |
| 705 | INFO exp: Request from Experiment Script: Wait for 10s.... |
| 706 | INFO property.packetsize: packetsize = 512 (Fixnum) |
| 707 | INFO exp: Request from Experiment Script: Wait for 10s.... |
| 708 | INFO property.packetsize: packetsize = 1024 (Fixnum) |
| 709 | INFO exp: Request from Experiment Script: Wait for 10s.... |
| 710 | INFO exp: All applications stopped. |
| 711 | INFO EXPERIMENT_DONE: Event triggered. Starting the associated tasks. |
| 712 | INFO NodeHandler: |
| 713 | INFO NodeHandler: Shutting down experiment, please wait... |
| 714 | INFO NodeHandler: |
| 715 | INFO run: Experiment gimi20-2012-10-18t13.51.41-04.00 finished after 0:56 |
| 716 | }}} |
| 717 | ---- |
| 718 | |
| 719 | [[BR]] |
| 720 | [[BR]] |
| 721 | |
| 722 | |
| 723 | [[http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Slice Back to previous step]] |
| 724 | |
| 725 | [[http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/Observe Forward to next step]] |
| 726 | |
| 727 | [[http://groups.geni.net/geni/wiki/GIMIv1.1Tutorial/ Back to tutorial main page]] |