Changes between Version 1 and Version 2 of GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Finish


Ignore:
Timestamp:
06/21/13 23:08:57 (6 years ago)
Author:
divyashri.bhat@gmail.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Finish

    v1 v2  
    1 === C.1 Initial Setup ===
    2 
    3 === C.1.1 Starting the OML Server (if needed) ===
    4 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.
    5    * 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.)
    6 {{{
    7 #!html
    8 <span style="color:red">DO NOT perform this task in the tutorial.
    9 </span>
    10 }}}
    11 
    12  This is explained the [OML installation file].
    13 
    14 {{{
    15 $ /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
    16 }}}
    17 
    18 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/GIMI-GEC16-Tutorials/GIMI-GEC16-TutorialB/Orchestrate/oml2-server-hook.sh (oml2-server-hook.sh)].
    19 
    20 {{{
    21 #!/bin/bash
    22 #
    23 # Example event hook for the OML server, copying an Sqlite database elsewhere
    24 # when the last client has exited.
    25 # Copyright 2012-2013 National ICT Australia (NICTA), Australia
    26 #
    27 # Permission is hereby granted, free of charge, to any person obtaining a copy
    28 # of this software and associated documentation files (the "Software"), to deal
    29 # in the Software without restriction, including without limitation the rights
    30 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    31 # copies of the Software, and to permit persons to whom the Software is
    32 # furnished to do so, subject to the following conditions:
    33 #
    34 # The above copyright notice and this permission notice shall be included in
    35 # all copies or substantial portions of the Software.
    36 #
    37 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    38 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    39 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    40 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    41 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    42 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    43 # THE SOFTWARE.
    44 #
    45 irodsUserName=rods
    46 irodsHost=emmy9.casa.umass.edu
    47 irodsPort=1247
    48 irodsZone=geniRenci
    49 HOME=/home/oml2
    50 export irodsUserName irodsHost irodsPort irodsZone HOME
    51 
    52 LOGFILE=/tmp/oml2-server-hook.log
    53 function log ()
    54 {
    55         echo "$@" >&2
    56         echo "$@" >> ${LOGFILE}
    57 }
    58 
    59 # XXX: You might need to initialise the iRODS password for the UNIX user
    60 # running tho oml2-server by running 'iinit' to create ~/.irods/.irodsA on its
    61 # behalf for iput to work
    62 IPUT=/usr/bin/iput
    63 SQLITE3=sqlite3
    64 PGDUMP=pg_dump
    65 
    66 echo "OML HOOK READY"
    67 log "OML HOOK READY"
    68 
    69 while read COMMAND ARGUMENTS; do
    70         # One report line must be printed in each control path;
    71         # this first one puts out a timestamp and a dump of the received command, but no newline
    72         log -n "`date`: ${COMMAND} ${ARGUMENTS}: "
    73         case "${COMMAND}" in
    74                 "DBCLOSED")
    75                         case "${ARGUMENTS}" in
    76                                 file:*)
    77                                         DBFILE=${ARGUMENTS/file:/}
    78                                         log "${IPUT} ${OPTION} ${DBFILE}"
    79                                         NAME=${DBFILE:14:6};
    80                                         FILE=${DBFILE:14};
    81                                         LENGTH=${#FILE}
    82                                         SLICE=${FILE:0:$LENGTH-4}
    83                                         DATE=`date`
    84                                         log "b db ${DBFILE} closed, pushing to iRODS..."
    85                                         ${IPUT} -f ${DBFILE} /geniRenci/home/$NAME/ #$FILE
    86                                         log "an iRODS operation finished"
    87                                         ;;
    88                                 postgresql://*)
    89                                         # Separate the components of the URI by gradually eating them off the TMP variable
    90                                        
    91                                         DOMAIN=${ARGUMENTS//*\//}       # cut everything before the final '/'
    92                                         USERNAME=${DOMAIN/-*/}          # get the first part before the '-'
    93                                         REST=${DOMAIN/$USERNAME-/}      # remove the username from the rest
    94                                         EXPNAME=${REST/-*/}             # same as for the username
    95                                         TIMESTAMP=${REST//*-/}          # get the last part after the '-'
    96 
    97                                                
    98                                         TMP="${ARGUMENTS/postgresql:\/\//}"
    99                                         USER=${TMP/@*/}
    100                                         TMP=${TMP/${USER}@/}
    101                                         HOST=${TMP/:*/}
    102                                         TMP=${TMP/${HOST}:/}
    103                                         PORT=${TMP/\/*/}
    104                                         TMP=${TMP/${PORT}\//}
    105                                         DBNAME=${TMP}
    106                                         DBFILE=${DBNAME}.`date +%Y-%m-%d_%H:%M:%S%z`.pg.sql
    107                                         log "PostgreSQL DB ${DBNAME} closed, dumping as ${DBFILE} and pushing to iRODS"
    108                                         log "User ${USER} Host ${HOST} Port ${PORT} DBNAME ${DBNAME} Home ${HOME}"
    109                                         ${PGDUMP} -U ${USER} -h ${HOST} -p ${PORT} ${DBNAME} > /tmp/${DBFILE}
    110                                         log "Before IPUT"
    111                                         log "${IPUT} -f /tmp/${DBFILE} /geniRenci/home/rods/"
    112                                         log `${IPUT} -V -f /tmp/${DBFILE} /geniRenci/home/rods/ 2>&1`
    113                                         # ${IPUT} -f /tmp/${DBFILE} /geniRenci/home/rods/
    114                                         ${IPUT} -f /tmp/${DBFILE} /geniRenci/home/${USERNAME}/experiments/${EXPNAME}-${TIMESTAMP}/measurements.sql
    115                                         log "After IPUT"
    116                                         ;;
    117                                 *)
    118                                         log "DB ${ARGUMENTS} closed, but don't know how to handle it"
    119                                         ;;
    120                         esac
    121                         ;;
    122                 "EXIT")
    123                         log "Exiting"
    124                         exit 0
    125                         ;;
    126                 *)
    127                         log "Unknown command"
    128                         ;;
    129         esac
    130 done
    131 
    132 }}}
    133 
    134 At the [http://groups.geni.net/geni/wiki/GIMI-GEC16-Tutorials/GIMI-GEC16-TutorialB/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.
    135 
    136 ----
    137 
    138 === C.1.2 Verification of Topology ===
    139 After establishing the slice on which the experiment will be executed, the experimenter will be most likely
    140 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.
    141 [[BR]]
    142 The following figure shows that a total of 12 (between each pair of nodes and in each direction) ping are performed.
    143 
    144 [[Image(ping.png)]]
    145 
    146 {{{
    147 defProperty('source1', "nodeA", "ID of a resource")
    148 defProperty('source2', "nodeB", "ID of a resource")
    149 defProperty('source3', "nodeC", "ID of a resource")
    150 defProperty('source4', "nodeD", "ID of a resource")
    151 defProperty('source5', "nodeE", "ID of a resource")
    152 
    153 #defProperty('sink1', "nodeA", "ID of a sink")
    154 #defProperty('sink2', "nodeB", "ID of a sink")
    155 #defProperty('sink3', "nodeC", "ID of a sink")
    156 #defProperty('sink4', "nodeD", "ID of a sink")
    157 #defProperty('sink5', "nodeE", "ID of a sink")
    158 
    159 defProperty('sinkaddr11', '192.168.4.10', "Ping destination address")
    160 defProperty('sinkaddr12', '192.168.5.12', "Ping destination address")
    161 
    162 defProperty('sinkaddr21', '192.168.4.11', "Ping destination address")
    163 defProperty('sinkaddr22', '192.168.2.12', "Ping destination address")
    164 defProperty('sinkaddr23', '192.168.1.13', "Ping destination address")
    165 
    166 defProperty('sinkaddr31', '192.168.5.11', "Ping destination address")
    167 defProperty('sinkaddr32', '192.168.2.10', "Ping destination address")
    168 defProperty('sinkaddr33', '192.168.3.13', "Ping destination address")
    169 defProperty('sinkaddr34', '192.168.6.14', "Ping destination address")
    170 
    171 defProperty('sinkaddr41', '192.168.1.10', "Ping destination address")
    172 defProperty('sinkaddr42', '192.168.3.12', "Ping destination address")
    173 
    174 defProperty('sinkaddr51', '192.168.6.12', "Ping destination address")
    175 
    176 defApplication('ping_app', 'pingmonitor') do |a|
    177     a.path = "/root/pingWrap.rb"
    178     a.version(1, 2, 0)
    179     a.shortDescription = "Wrapper around ping"
    180     a.description = "ping application"
    181     a.defProperty('dest_addr', 'Address to ping', '-a', {:type => :string, :dynamic => false})
    182     a.defProperty('count', 'Number of times to ping', '-c', {:type => :integer, :dynamic => false})
    183     a.defProperty('interval', 'Interval between pings in s', '-i', {:type => :integer, :dynamic => false})
    184 
    185     a.defMeasurement('myping') do |m|
    186      m.defMetric('dest_addr',:string)
    187      m.defMetric('ttl',:int)
    188      m.defMetric('rtt',:float)
    189      m.defMetric('rtt_unit',:string)
    190    end
    191 end
    192 
    193 defGroup('Source1', property.source1) do |node|
    194   node.addApplication("ping_app") do |app|
    195     app.setProperty('dest_addr', property.sinkaddr11)
    196     app.setProperty('count', 30)
    197     app.setProperty('interval', 1)
    198     app.measure('myping', :samples => 1)
    199   end
    200 
    201   node.addApplication("ping_app") do |app|
    202     app.setProperty('dest_addr', property.sinkaddr12)
    203     app.setProperty('count', 30)
    204     app.setProperty('interval', 1)
    205     app.measure('myping', :samples => 1)
    206   end
    207 end
    208 
    209 defGroup('Source2', property.source2) do |node|
    210   node.addApplication("ping_app") do |app|
    211     app.setProperty('dest_addr', property.sinkaddr21)
    212     app.setProperty('count', 30)
    213     app.setProperty('interval', 1)
    214     app.measure('myping', :samples => 1)
    215   end
    216 
    217   node.addApplication("ping_app") do |app|
    218     app.setProperty('dest_addr', property.sinkaddr22)
    219     app.setProperty('count', 30)
    220     app.setProperty('interval', 1)
    221     app.measure('myping', :samples => 1)
    222   end
    223 
    224   node.addApplication("ping_app") do |app|
    225     app.setProperty('dest_addr', property.sinkaddr23)
    226     app.setProperty('count', 30)
    227     app.setProperty('interval', 1)
    228     app.measure('myping', :samples => 1)
    229   end
    230 end
    231 
    232 defGroup('Source3', property.source3) do |node|
    233   node.addApplication("ping_app") do |app|
    234     app.setProperty('dest_addr', property.sinkaddr31)
    235     app.setProperty('count', 30)
    236     app.setProperty('interval', 1)
    237     app.measure('myping', :samples => 1)
    238   end
    239 
    240   node.addApplication("ping_app") do |app|
    241     app.setProperty('dest_addr', property.sinkaddr32)
    242     app.setProperty('count', 30)
    243     app.setProperty('interval', 1)
    244     app.measure('myping', :samples => 1)
    245   end
    246 
    247   node.addApplication("ping_app") do |app|
    248     app.setProperty('dest_addr', property.sinkaddr33)
    249     app.setProperty('count', 30)
    250     app.setProperty('interval', 1)
    251     app.measure('myping', :samples => 1)
    252   end
    253 
    254   node.addApplication("ping_app") do |app|
    255     app.setProperty('dest_addr', property.sinkaddr34)
    256     app.setProperty('count', 30)
    257     app.setProperty('interval', 1)
    258     app.measure('myping', :samples => 1)
    259   end
    260 end
    261 
    262 defGroup('Source4', property.source4) do |node|
    263 
    264   node.addApplication("ping_app") do |app|
    265     app.setProperty('dest_addr', property.sinkaddr41)
    266     app.setProperty('count', 30)
    267     app.setProperty('interval', 1)
    268     app.measure('myping', :samples => 1)
    269   end
    270 
    271   node.addApplication("ping_app") do |app|
    272     app.setProperty('dest_addr', property.sinkaddr42)
    273     app.setProperty('count', 30)
    274     app.setProperty('interval', 1)
    275     app.measure('myping', :samples => 1)
    276   end
    277 end
    278 
    279 defGroup('Source5', property.source5) do |node|
    280   node.addApplication("ping_app") do |app|
    281     app.setProperty('dest_addr', property.sinkaddr51)
    282     app.setProperty('count', 30)
    283     app.setProperty('interval', 1)
    284     app.measure('myping', :samples => 1)
    285   end
    286 end
    287 
    288 onEvent(:ALL_UP_AND_INSTALLED) do |event|
    289   info "Starting the ping"
    290   allGroups.startApplications
    291   wait 5
    292   info "Stopping the ping"
    293   allGroups.stopApplications
    294   Experiment.done
    295 end
    296 }}}
    297 
    298 The script is executed from the user workspace as follows:
    299 
    300 {{{
    301 $ cd ~/Tutorials/GIMI/common/
    302 $ omf-5.4 exec --no-am -e gimiXX-ping_all -S gimiXX step1-ping_all.rb
    303 }}}
    304 
    305 Where gimiXX has to be replaced by the slice name you are using for your experiment.
    306 
    307 You should see the following output after executing the omf command.
    308 
    309 {{{
    310  INFO NodeHandler: OMF Experiment Controller 5.4 (git e0eefcf)
    311  INFO NodeHandler: Slice ID: gimi20
    312  INFO NodeHandler: Experiment ID: gimi20-2012-10-18t14.03.42-04.00
    313  INFO NodeHandler: Message authentication is disabled
    314  WARN NodeHandler: AM support disabled - any service calls will fail!
    315  INFO Experiment: load system:exp:stdlib
    316  INFO property.resetDelay: resetDelay = 210 (Fixnum)
    317  INFO property.resetTries: resetTries = 1 (Fixnum)
    318  INFO Experiment: load system:exp:eventlib
    319  INFO Experiment: load ping_all.rb
    320  INFO property.source1: source1 = "nodeA" (String)
    321  INFO property.source2: source2 = "nodeB" (String)
    322  INFO property.source3: source3 = "nodeC" (String)
    323  INFO property.source4: source4 = "nodeD" (String)
    324  INFO property.source5: source5 = "nodeE" (String)
    325  INFO property.sinkaddr11: sinkaddr11 = "192.168.4.10" (String)
    326  INFO property.sinkaddr12: sinkaddr12 = "192.168.5.12" (String)
    327  INFO property.sinkaddr21: sinkaddr21 = "192.168.4.11" (String)
    328  INFO property.sinkaddr22: sinkaddr22 = "192.168.2.12" (String)
    329  INFO property.sinkaddr23: sinkaddr23 = "192.168.1.13" (String)
    330  INFO property.sinkaddr31: sinkaddr31 = "192.168.5.11" (String)
    331  INFO property.sinkaddr32: sinkaddr32 = "192.168.2.10" (String)
    332  INFO property.sinkaddr33: sinkaddr33 = "192.168.3.13" (String)
    333  INFO property.sinkaddr34: sinkaddr34 = "192.168.6.14" (String)
    334  INFO property.sinkaddr41: sinkaddr41 = "192.168.1.10" (String)
    335  INFO property.sinkaddr42: sinkaddr42 = "192.168.3.12" (String)
    336  INFO property.sinkaddr51: sinkaddr51 = "192.168.6.12" (String)
    337  INFO Topology: Loading topology 'nodeA'.
    338  INFO Topology: Loading topology 'nodeB'.
    339  INFO Topology: Loading topology 'nodeC'.
    340  INFO Topology: Loading topology 'nodeD'.
    341  INFO Topology: Loading topology 'nodeE'.
    342  INFO Experiment: Switching ON resources which are OFF
    343  INFO ALL_UP_AND_INSTALLED: Event triggered. Starting the associated tasks.
    344  INFO exp: Starting the ping
    345  INFO exp: Request from Experiment Script: Wait for 5s....
    346  INFO exp: Stopping the ping
    347  INFO EXPERIMENT_DONE: Event triggered. Starting the associated tasks.
    348  INFO NodeHandler:
    349  INFO NodeHandler: Shutting down experiment, please wait...
    350  INFO NodeHandler:
    351  INFO run: Experiment gimi20-2012-10-18t14.03.42-04.00 finished after 0:16
    352 }}}
    353 
    354 ----
    355 
    356 === C.1.3 Setup Routing in Experiment Topology ===
    357 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.
    358 
    359 {{{
    360 defGroup('Node1', "nodeA")
    361 defGroup('Node2', "nodeB")
    362 defGroup('Node3', "nodeC")
    363 defGroup('Node4', "nodeD")
    364 defGroup('Node5', "nodeE")
    365 
    366 
    367 onEvent(:ALL_UP) do |event|
    368   wait 1
    369   info 'Changing routing setup'
    370 
    371   group('Node1').exec("route add -net 192.168.1.0/24 gw 192.168.4.10")
    372   group('Node1').exec("route add -net 192.168.2.0/24 gw 192.168.4.10")
    373   group('Node1').exec("route add -net 192.168.3.0/24 gw 192.168.5.12")
    374   group('Node1').exec("route add -net 192.168.6.0/24 gw 192.168.5.12")
    375   group('Node1').exec("echo 1 >  /proc/sys/net/ipv4/ip_forward")
    376 
    377   group('Node2').exec("route add -net 192.168.3.0/24 gw 192.168.1.13")
    378   group('Node2').exec("route add -net 192.168.5.0/24 gw 192.168.4.11")
    379   group('Node2').exec("route add -net 192.168.6.0/24 gw 192.168.2.12")
    380   group('Node2').exec("echo 1 >  /proc/sys/net/ipv4/ip_forward")
    381 
    382   group('Node3').exec("route add -net 192.168.1.0/24 gw 192.168.3.13")
    383   group('Node3').exec("route add -net 192.168.4.0/24 gw 192.168.5.11")
    384   group('Node3').exec("echo 1 >  /proc/sys/net/ipv4/ip_forward")
    385 
    386   group('Node4').exec("route add -net 192.168.2.0/24 gw 192.168.3.12")
    387   group('Node4').exec("route add -net 192.168.4.0/24 gw 192.168.1.10")
    388   group('Node4').exec("route add -net 192.168.5.0/24 gw 192.168.3.12")
    389   group('Node4').exec("route add -net 192.168.6.0/24 gw 192.168.3.12")
    390   group('Node4').exec("echo 1 >  /proc/sys/net/ipv4/ip_forward")
    391 
    392   group('Node5').exec("route add -net 192.168.2.0/24 gw 192.168.6.12")
    393   group('Node5').exec("route add -net 192.168.1.0/24 gw 192.168.6.12")
    394   group('Node5').exec("route add -net 192.168.3.0/24 gw 192.168.6.12")
    395   group('Node5').exec("route add -net 192.168.4.0/24 gw 192.168.6.12")
    396   group('Node5').exec("route add -net 192.168.5.0/24 gw 192.168.6.12")
    397 
    398   info 'Routing setup finished'
    399   wait 5
    400   info 'Stopping applications'
    401   allGroups.stopApplications
    402   wait 1
    403   Experiment.done
    404 end
    405 }}}
    406 
    407 This script can be easily adapted if the experimenter wishes to set up the routing between the nodes
    408 differently.
    409 
    410 The script is executed from the user workspace as follows:
    411 
    412 {{{
    413 $ cd ~/Tutorials/GIMI/common/
    414 $ omf-5.4 exec --no-am -e gimiXX-routing -S gimiXX step2-routing.rb
    415 }}}
    416 
    417 Where gimiXX has to be replaced by the slice name you are using for your experiment.
    418 
    419 You should see the following output after executing the omf command.
    420 
    421 {{{
    422  INFO NodeHandler: OMF Experiment Controller 5.4 (git e0eefcf)
    423  INFO NodeHandler: Slice ID: gimi20
    424  INFO NodeHandler: Experiment ID: gimi20-2012-10-18t14.14.10-04.00
    425  INFO NodeHandler: Message authentication is disabled
    426  WARN NodeHandler: AM support disabled - any service calls will fail!
    427  INFO Experiment: load system:exp:stdlib
    428  INFO property.resetDelay: resetDelay = 210 (Fixnum)
    429  INFO property.resetTries: resetTries = 1 (Fixnum)
    430  INFO Experiment: load system:exp:eventlib
    431  INFO Experiment: load routing.rb
    432  INFO Topology: Loading topology 'nodeA'.
    433  INFO Topology: Loading topology 'nodeB'.
    434  INFO Topology: Loading topology 'nodeC'.
    435  INFO Topology: Loading topology 'nodeD'.
    436  INFO Topology: Loading topology 'nodeE'.
    437  INFO Experiment: Switching ON resources which are OFF
    438  INFO ALL_UP: Event triggered. Starting the associated tasks.
    439  INFO exp: Request from Experiment Script: Wait for 1s....
    440  INFO exp: Changing routing setup
    441  INFO exp: Routing setup finished
    442  INFO exp: Request from Experiment Script: Wait for 5s....
    443  INFO exp: Stopping applications
    444  INFO exp: Request from Experiment Script: Wait for 1s....
    445  INFO EXPERIMENT_DONE: Event triggered. Starting the associated tasks.
    446  INFO NodeHandler:
    447  INFO NodeHandler: Shutting down experiment, please wait...
    448  INFO NodeHandler:
    449  INFO run: Experiment gimi20-2012-10-18t14.14.10-04.00 finished after 0:16
    450 }}}
    451 
    452 ----
    453 
    454 === C.1.4 Verification of Routing ===
    455 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.
    456 
    457 [[Image(GIMIPing_e2e.png)]]
    458 
    459 {{{
    460 defProperty('source1', "nodeA", "ID of a resource")
    461 defProperty('source2', "nodeB", "ID of a resource")
    462 defProperty('source3', "nodeC", "ID of a resource")
    463 defProperty('source4', "nodeD", "ID of a resource")
    464 defProperty('source5', "nodeE", "ID of a resource")
    465 
    466 defProperty('sinkaddr11', '192.168.1.13', "Ping destination address")
    467 defProperty('sinkaddr12', '192.168.3.13', "Ping destination address")
    468 defProperty('sinkaddr13', '192.168.6.14', "Ping destination address")
    469 
    470 defProperty('sinkaddr21', '192.168.6.14', "Ping destination address")
    471 
    472 defProperty('sinkaddr41', '192.168.4.11', "Ping destination address")
    473 defProperty('sinkaddr42', '192.168.5.11', "Ping destination address")
    474 defProperty('sinkaddr43', '192.168.6.14', "Ping destination address")
    475 
    476 defProperty('sinkaddr51', '192.168.5.11', "Ping destination address")
    477 defProperty('sinkaddr52', '192.168.2.10', "Ping destination address")
    478 defProperty('sinkaddr53', '192.168.3.13', "Ping destination address")
    479 
    480 defApplication('ping_app', 'pingmonitor') do |a|
    481         a.path = "/root/pingWrap.rb"
    482         a.version(1, 2, 0)
    483         a.shortDescription = "Wrapper around ping"
    484         a.description = "ping application"
    485         a.defProperty('dest_addr', 'Address to ping', '-a', {:type => :string, :dynamic => false})
    486         a.defProperty('count', 'Number of times to ping', '-c', {:type => :integer, :dynamic => false})
    487         a.defProperty('interval', 'Interval between pings in s', '-i', {:type => :integer, :dynamic => false})
    488        
    489         a.defMeasurement('myping') do |m|
    490             m.defMetric('dest_addr',:string)
    491             m.defMetric('ttl',:int)
    492             m.defMetric('rtt',:float)
    493             m.defMetric('rtt_unit',:string)
    494         end
    495 end
    496 
    497 defGroup('Source1', property.source1) do |node|
    498       node.addApplication("ping_app") do |app|
    499           app.setProperty('dest_addr', property.sinkaddr11)
    500           app.setProperty('count', 30)
    501           app.setProperty('interval', 1)
    502           app.measure('myping', :samples => 1)
    503       end
    504      
    505       node.addApplication("ping_app") do |app|
    506           app.setProperty('dest_addr', property.sinkaddr12)
    507           app.setProperty('count', 30)
    508           app.setProperty('interval', 1)
    509           app.measure('myping', :samples => 1)
    510       end
    511 
    512       node.addApplication("ping_app") do |app|         
    513           app.setProperty('dest_addr', property.sinkaddr13)
    514           app.setProperty('count', 30)             
    515           app.setProperty('interval', 1)                 
    516           app.measure('myping', :samples => 1)
    517       end
    518 end
    519 
    520 defGroup('Source2', property.source1) do |node|
    521     node.addApplication("ping_app") do |app|             
    522         app.setProperty('dest_addr', property.sinkaddr21)       
    523         app.setProperty('count', 30)           
    524         app.setProperty('interval', 1)               
    525         app.measure('myping', :samples => 1)                 
    526     end               
    527 end
    528 
    529 defGroup('Source4', property.source3) do |node|
    530       node.addApplication("ping_app") do |app|
    531           app.setProperty('dest_addr', property.sinkaddr41)
    532           app.setProperty('count', 30)
    533           app.setProperty('interval', 1)
    534           app.measure('myping', :samples => 1)
    535       end
    536 
    537       node.addApplication("ping_app") do |app|
    538           app.setProperty('dest_addr', property.sinkaddr42)
    539           app.setProperty('count', 30)
    540           app.setProperty('interval', 1)
    541           app.measure('myping', :samples => 1)
    542       end
    543 
    544       node.addApplication("ping_app") do |app|
    545           app.setProperty('dest_addr', property.sinkaddr43)
    546           app.setProperty('count', 30)
    547           app.setProperty('interval', 1)
    548           app.measure('myping', :samples => 1)
    549       end
    550 end
    551 
    552 defGroup('Source5', property.source3) do |node|
    553           node.addApplication("ping_app") do |app|
    554               app.setProperty('dest_addr', property.sinkaddr51)
    555               app.setProperty('count', 30)
    556               app.setProperty('interval', 1)
    557               app.measure('myping', :samples => 1)
    558           end
    559 
    560           node.addApplication("ping_app") do |app|
    561               app.setProperty('dest_addr', property.sinkaddr52)
    562               app.setProperty('count', 30)
    563               app.setProperty('interval', 1)
    564               app.measure('myping', :samples => 1)
    565           end
    566 
    567           node.addApplication("ping_app") do |app|
    568               app.setProperty('dest_addr', property.sinkaddr53)
    569               app.setProperty('count', 30)
    570               app.setProperty('interval', 1)
    571               app.measure('myping', :samples => 1)
    572           end
    573 end
    574 
    575 onEvent(:ALL_UP_AND_INSTALLED) do |event|
    576       info "Starting the ping"
    577       allGroups.startApplications
    578       wait 5
    579       info "Stopping the ping"
    580       allGroups.stopApplications
    581       Experiment.done
    582 end
    583 }}}
    584 
    585 The script is executed from the user workspace as follows:
    586 
    587 {{{
    588 $ cd ~/Tutorials/GIMI/common/
    589 $ omf-5.4 exec --no-am -e gimiXX-ping_e2e -S gimiXX step3-ping_e2e.rb
    590 }}}
    591 
    592 Where gimiXX has to be replaced by the slice name you are using for your experiment.
    593 
    594 You should see the following output after executing the omf command.
    595 
    596 {{{
    597  INFO NodeHandler: OMF Experiment Controller 5.4 (git e0eefcf)
    598  INFO NodeHandler: Slice ID: gimi20
    599  INFO NodeHandler: Experiment ID: gimi20-2012-10-18t14.03.42-04.00
    600  INFO NodeHandler: Message authentication is disabled
    601  WARN NodeHandler: AM support disabled - any service calls will fail!
    602  INFO Experiment: load system:exp:stdlib
    603  INFO property.resetDelay: resetDelay = 210 (Fixnum)
    604  INFO property.resetTries: resetTries = 1 (Fixnum)
    605  INFO Experiment: load system:exp:eventlib
    606  INFO Experiment: load ping_all.rb
    607  INFO property.source1: source1 = "nodeA" (String)
    608  INFO property.source2: source2 = "nodeB" (String)
    609  INFO property.source3: source3 = "nodeC" (String)
    610  INFO property.source4: source4 = "nodeD" (String)
    611  INFO property.source5: source5 = "nodeE" (String)
    612  INFO property.sinkaddr11: sinkaddr11 = "192.168.4.10" (String)
    613  INFO property.sinkaddr12: sinkaddr12 = "192.168.5.12" (String)
    614  INFO property.sinkaddr21: sinkaddr21 = "192.168.4.11" (String)
    615  INFO property.sinkaddr22: sinkaddr22 = "192.168.2.12" (String)
    616  INFO property.sinkaddr23: sinkaddr23 = "192.168.1.13" (String)
    617  INFO property.sinkaddr31: sinkaddr31 = "192.168.5.11" (String)
    618  INFO property.sinkaddr32: sinkaddr32 = "192.168.2.10" (String)
    619  INFO property.sinkaddr33: sinkaddr33 = "192.168.3.13" (String)
    620  INFO property.sinkaddr34: sinkaddr34 = "192.168.6.14" (String)
    621  INFO property.sinkaddr41: sinkaddr41 = "192.168.1.10" (String)
    622  INFO property.sinkaddr42: sinkaddr42 = "192.168.3.12" (String)
    623  INFO property.sinkaddr51: sinkaddr51 = "192.168.6.12" (String)
    624  INFO Topology: Loading topology 'nodeA'.
    625  INFO Topology: Loading topology 'nodeB'.
    626  INFO Topology: Loading topology 'nodeC'.
    627  INFO Topology: Loading topology 'nodeD'.
    628  INFO Topology: Loading topology 'nodeE'.
    629  INFO Experiment: Switching ON resources which are OFF
    630  INFO ALL_UP_AND_INSTALLED: Event triggered. Starting the associated tasks.
    631  INFO exp: Starting the ping
    632  INFO exp: Request from Experiment Script: Wait for 5s....
    633  INFO exp: Stopping the ping
    634  INFO EXPERIMENT_DONE: Event triggered. Starting the associated tasks.
    635  INFO NodeHandler:
    636  INFO NodeHandler: Shutting down experiment, please wait...
    637  INFO NodeHandler:
    638  INFO run: Experiment gimi20-2012-10-18t14.03.42-04.00 finished after 0:16
    639 }}}
    640 
    641 ----
    642 
    643 === C.2 Running Actual Experiment ===
    644 
    645 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.
    646 
    647 [[Image(otg_nmetrics.png)]]
    648 
    649 
    650 
    651 The one we use for this tutorial is shown below.
    652 
    653 {{{
    654 defProperty('theSender','nodeB','ID of sender node')
    655 defProperty('theReceiver1', 'nodeE', "ID of receiver node")
    656 defProperty('theReceiver2', 'nodeA', "ID of receiver node")
    657 defProperty('theReceiver3', 'nodeD', "ID of receiver node")
    658 defProperty('packetsize', 128, "Packet size (byte) from the sender node")
    659 defProperty('bitrate', 2048, "Bitrate (bit/s) from the sender node")
    660 defProperty('runtime', 40, "Time in second for the experiment is to run")
    661 
    662 defGroup('Sender',property.theSender) do |node|
    663     options = { 'sample-interval' => 2 }
    664     node.addPrototype("system_monitor", options)
    665     node.addApplication("test:app:otg2") do |app|
    666         app.setProperty('udp:local_host', '192.168.2.10')
    667         app.setProperty('udp:dst_host', '192.168.6.14')
    668         app.setProperty('udp:dst_port', 3000)
    669         app.setProperty('cbr:size', property.packetsize)
    670         app.setProperty('cbr:rate', property.bitrate * 2)
    671         app.measure('udp_out', :samples => 1)
    672     end
    673    
    674     node.addApplication("test:app:otg2") do |app|
    675         app.setProperty('udp:local_host', '192.168.4.10')
    676         app.setProperty('udp:dst_host', '192.168.4.11')
    677         app.setProperty('udp:dst_port', 3000)
    678         app.setProperty('cbr:size', property.packetsize)
    679         app.setProperty('cbr:rate', property.bitrate * 2)
    680         app.measure('udp_out', :samples => 1)
    681     end
    682    
    683     node.addApplication("test:app:otg2") do |app|
    684         app.setProperty('udp:local_host', '192.168.1.10')
    685         app.setProperty('udp:dst_host', '192.168.1.13')
    686         app.setProperty('udp:dst_port', 3000)                                   
    687         app.setProperty('cbr:size', property.packetsize)                                           
    688         app.setProperty('cbr:rate', property.bitrate * 2)                                                   
    689         app.measure('udp_out', :samples => 1)                                                       
    690     end
    691 end
    692 
    693 defGroup('Receiver1',property.theReceiver1) do |node|
    694     options = { 'sample-interval' => 2 }
    695     node.addPrototype("system_monitor", options)
    696 
    697     node.addApplication("test:app:otr2") do |app|
    698         app.setProperty('udp:local_host', '192.168.6.14')
    699         app.setProperty('udp:local_port', 3000)
    700         app.measure('udp_in', :samples => 1)
    701     end
    702 end
    703 
    704 defGroup('Receiver2',property.theReceiver2) do |node|
    705     options = { 'sample-interval' => 2 }
    706     node.addPrototype("system_monitor", options)
    707     node.addApplication("test:app:otr2") do |app|
    708         app.setProperty('udp:local_host', '192.168.4.11')
    709         app.setProperty('udp:local_port', 3000)
    710         app.measure('udp_in', :samples => 1)
    711     end
    712 end
    713 
    714 defGroup('Receiver3',property.theReceiver3) do |node|     
    715     options = { 'sample-interval' => 2 }
    716     node.addPrototype("system_monitor", options)
    717     node.addApplication("test:app:otr2") do |app|                   
    718         app.setProperty('udp:local_host', '192.168.1.13')
    719         app.setProperty('udp:local_port', 3000)                               
    720         app.measure('udp_in', :samples => 1)                                   
    721     end
    722 end
    723 
    724 onEvent(:ALL_UP_AND_INSTALLED) do |event|
    725     info "starting"
    726     wait 5
    727     allGroups.exec("ln -s /usr/local/bin/otr2 /usr/bin/otr2")
    728     allGroups.exec("ln -s /usr/local/bin/otg2 /usr/bin/otg2")
    729     allGroups.exec("ln -s /usr/local/bin/oml2-nmetrics /usr/bin/oml2-nmetrics")
    730     allGroups.startApplications
    731     info "All applications started..."
    732     wait property.runtime / 4
    733     property.packetsize = 256
    734     wait property.runtime / 4
    735     property.packetsize = 512
    736     wait property.runtime / 4
    737     property.packetsize = 1024
    738     wait property.runtime / 4
    739     allGroups.stopApplications
    740     info "All applications stopped."
    741     Experiment.done
    742 end
    743 }}}
    744 
    745 The script is executed from the user workspace as follows:
    746 
    747 {{{
    748 $ cd ~/Tutorials/GIMI/common/
    749 $ omf-5.4 exec --no-am -e gimiXX-otg_nmetrics -S gimiXX step4-otg_nmetrics.rb
    750 }}}
    751 
    752 Where gimiXX has to be replaced by the slice name you are using for your experiment.
    753 
    754 You should see the following output (or similar) after executing the omf command.
    755 
    756 {{{
    757  INFO NodeHandler: OMF Experiment Controller 5.4 (git e0eefcf)
    758  INFO NodeHandler: Slice ID: gimi20
    759  INFO NodeHandler: Experiment ID: gimi20-2012-10-18t13.51.41-04.00
    760  INFO NodeHandler: Message authentication is disabled
    761  WARN NodeHandler: AM support disabled - any service calls will fail!
    762  INFO Experiment: load system:exp:stdlib
    763  INFO property.resetDelay: resetDelay = 210 (Fixnum)
    764  INFO property.resetTries: resetTries = 1 (Fixnum)
    765  INFO Experiment: load system:exp:eventlib
    766  INFO Experiment: load otg_nmetrics.rb
    767  INFO property.theSender: theSender = "nodeB" (String)
    768  INFO property.theReceiver1: theReceiver1 = "nodeE" (String)
    769  INFO property.theReceiver2: theReceiver2 = "nodeA" (String)
    770  INFO property.theReceiver3: theReceiver3 = "nodeD" (String)
    771  INFO property.packetsize: packetsize = 128 (Fixnum)
    772  INFO property.bitrate: bitrate = 2048 (Fixnum)
    773  INFO property.runtime: runtime = 40 (Fixnum)
    774  INFO Topology: Loading topology 'nodeB'.
    775  INFO Topology: Loading topology 'nodeE'.
    776  INFO Topology: Loading topology 'nodeA'.
    777  INFO Topology: Loading topology 'nodeD'.
    778  INFO Experiment: Switching ON resources which are OFF
    779  INFO ALL_UP_AND_INSTALLED: Event triggered. Starting the associated tasks.
    780  INFO exp: starting
    781  INFO exp: Request from Experiment Script: Wait for 5s....
    782  INFO exp: All applications started...
    783  INFO exp: Request from Experiment Script: Wait for 10s....
    784  INFO property.packetsize: packetsize = 256 (Fixnum)
    785  INFO exp: Request from Experiment Script: Wait for 10s....
    786  INFO property.packetsize: packetsize = 512 (Fixnum)
    787  INFO exp: Request from Experiment Script: Wait for 10s....
    788  INFO property.packetsize: packetsize = 1024 (Fixnum)
    789  INFO exp: Request from Experiment Script: Wait for 10s....
    790  INFO exp: All applications stopped.
    791  INFO EXPERIMENT_DONE: Event triggered. Starting the associated tasks.
    792  INFO NodeHandler:
    793  INFO NodeHandler: Shutting down experiment, please wait...
    794  INFO NodeHandler:
    795  INFO run: Experiment gimi20-2012-10-18t13.51.41-04.00 finished after 0:56
    796 }}}
    797 ----
    798 
    799 [[BR]]
    800 [[BR]]