= Execute = {{{ #!html
Image Map
}}} == 3. Initial Setup == === 3.1 Starting the OML Server (if needed) === For this tutorial, you can skip this step. The OML Server is already running on [http://emmy9.casa.umass.edu Emmy9].[[BR]] At the [http://groups.geni.net/geni/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/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. ---- === 3.2 Verification of Topology === After establishing the slice on which the experiment will be executed, the experimenter will be most likely 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. [[BR]] The following figure shows that a total of 12 (between each pair of nodes and in each direction) ping are performed. [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/ping.png?format=raw)]] '''In !LabWiki''' [[BR]] step1-ping_oml.rb [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_4.png?format=raw)]] {{{ defProperty('source1', "nodeA", "ID of a resource") defProperty('source2', "nodeB", "ID of a resource") defProperty('source3', "nodeC", "ID of a resource") defProperty('source4', "nodeD", "ID of a resource") defProperty('source5', "nodeE", "ID of a resource") #defProperty('sink1', "nodeA", "ID of a sink") #defProperty('sink2', "nodeB", "ID of a sink") #defProperty('sink3', "nodeC", "ID of a sink") #defProperty('sink4', "nodeD", "ID of a sink") #defProperty('sink5', "nodeE", "ID of a sink") defProperty('sinkaddr11', '192.168.4.10', "Ping destination address") defProperty('sinkaddr12', '192.168.5.12', "Ping destination address") defProperty('sinkaddr21', '192.168.4.11', "Ping destination address") defProperty('sinkaddr22', '192.168.2.12', "Ping destination address") defProperty('sinkaddr23', '192.168.1.13', "Ping destination address") defProperty('sinkaddr31', '192.168.5.11', "Ping destination address") defProperty('sinkaddr32', '192.168.2.10', "Ping destination address") defProperty('sinkaddr33', '192.168.3.13', "Ping destination address") defProperty('sinkaddr34', '192.168.6.14', "Ping destination address") defProperty('sinkaddr41', '192.168.1.10', "Ping destination address") defProperty('sinkaddr42', '192.168.3.12', "Ping destination address") defProperty('sinkaddr51', '192.168.6.12', "Ping destination address") defApplication('ping_app', 'pingmonitor') do |a| a.path = "/root/pingWrap.rb" a.version(1, 2, 0) a.shortDescription = "Wrapper around ping" a.description = "ping application" a.defProperty('dest_addr', 'Address to ping', '-a', {:type => :string, :dynamic => false}) a.defProperty('count', 'Number of times to ping', '-c', {:type => :integer, :dynamic => false}) a.defProperty('interval', 'Interval between pings in s', '-i', {:type => :integer, :dynamic => false}) a.defMeasurement('myping') do |m| m.defMetric('dest_addr',:string) m.defMetric('ttl',:int) m.defMetric('rtt',:float) m.defMetric('rtt_unit',:string) end end defGroup('Source1', property.source1) do |node| node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr11) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr12) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end end defGroup('Source2', property.source2) do |node| node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr21) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr22) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr23) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end end defGroup('Source3', property.source3) do |node| node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr31) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr32) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr33) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr34) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end end defGroup('Source4', property.source4) do |node| node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr41) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr42) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end end defGroup('Source5', property.source5) do |node| node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr51) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end end onEvent(:ALL_UP_AND_INSTALLED) do |event| info "Starting the ping" allGroups.startApplications wait 5 info "Stopping the ping" allGroups.stopApplications Experiment.done end }}} === 3.3 Setup Routing in Experiment Topology === 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. '''In !LabWiki''' [[BR]] step2-routing.rb {{{ defGroup('Node1', "nodeA") defGroup('Node2', "nodeB") defGroup('Node3', "nodeC") defGroup('Node4', "nodeD") defGroup('Node5', "nodeE") onEvent(:ALL_UP) do |event| wait 1 info 'Changing routing setup' group('Node1').exec("route add -net 192.168.1.0/24 gw 192.168.4.10") group('Node1').exec("route add -net 192.168.2.0/24 gw 192.168.4.10") group('Node1').exec("route add -net 192.168.3.0/24 gw 192.168.5.12") group('Node1').exec("route add -net 192.168.6.0/24 gw 192.168.5.12") group('Node1').exec("echo 1 > /proc/sys/net/ipv4/ip_forward") group('Node2').exec("route add -net 192.168.3.0/24 gw 192.168.1.13") group('Node2').exec("route add -net 192.168.5.0/24 gw 192.168.4.11") group('Node2').exec("route add -net 192.168.6.0/24 gw 192.168.2.12") group('Node2').exec("echo 1 > /proc/sys/net/ipv4/ip_forward") group('Node3').exec("route add -net 192.168.1.0/24 gw 192.168.3.13") group('Node3').exec("route add -net 192.168.4.0/24 gw 192.168.5.11") group('Node3').exec("echo 1 > /proc/sys/net/ipv4/ip_forward") group('Node4').exec("route add -net 192.168.2.0/24 gw 192.168.3.12") group('Node4').exec("route add -net 192.168.4.0/24 gw 192.168.1.10") group('Node4').exec("route add -net 192.168.5.0/24 gw 192.168.3.12") group('Node4').exec("route add -net 192.168.6.0/24 gw 192.168.3.12") group('Node4').exec("echo 1 > /proc/sys/net/ipv4/ip_forward") group('Node5').exec("route add -net 192.168.2.0/24 gw 192.168.6.12") group('Node5').exec("route add -net 192.168.1.0/24 gw 192.168.6.12") group('Node5').exec("route add -net 192.168.3.0/24 gw 192.168.6.12") group('Node5').exec("route add -net 192.168.4.0/24 gw 192.168.6.12") group('Node5').exec("route add -net 192.168.5.0/24 gw 192.168.6.12") info 'Routing setup finished' wait 5 info 'Stopping applications' allGroups.stopApplications wait 1 Experiment.done end }}} This script can be easily adapted if the experimenter wishes to set up the routing between the nodes differently. === 3.4 Verification of Routing === 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. [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/GIMIPing_e2e.png?format=raw)]] '''In !LabWiki''' [[BR]] step3-ping_e2e.rb {{{ defProperty('source1', "nodeA", "ID of a resource") defProperty('source2', "nodeB", "ID of a resource") defProperty('source3', "nodeC", "ID of a resource") defProperty('source4', "nodeD", "ID of a resource") defProperty('source5', "nodeE", "ID of a resource") defProperty('sinkaddr11', '192.168.1.13', "Ping destination address") defProperty('sinkaddr12', '192.168.3.13', "Ping destination address") defProperty('sinkaddr13', '192.168.6.14', "Ping destination address") defProperty('sinkaddr21', '192.168.6.14', "Ping destination address") defProperty('sinkaddr41', '192.168.4.11', "Ping destination address") defProperty('sinkaddr42', '192.168.5.11', "Ping destination address") defProperty('sinkaddr43', '192.168.6.14', "Ping destination address") defProperty('sinkaddr51', '192.168.5.11', "Ping destination address") defProperty('sinkaddr52', '192.168.2.10', "Ping destination address") defProperty('sinkaddr53', '192.168.3.13', "Ping destination address") defApplication('ping_app', 'pingmonitor') do |a| a.path = "/root/pingWrap.rb" a.version(1, 2, 0) a.shortDescription = "Wrapper around ping" a.description = "ping application" a.defProperty('dest_addr', 'Address to ping', '-a', {:type => :string, :dynamic => false}) a.defProperty('count', 'Number of times to ping', '-c', {:type => :integer, :dynamic => false}) a.defProperty('interval', 'Interval between pings in s', '-i', {:type => :integer, :dynamic => false}) a.defMeasurement('myping') do |m| m.defMetric('dest_addr',:string) m.defMetric('ttl',:int) m.defMetric('rtt',:float) m.defMetric('rtt_unit',:string) end end defGroup('Source1', property.source1) do |node| node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr11) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr12) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr13) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end end defGroup('Source2', property.source1) do |node| node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr21) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end end defGroup('Source4', property.source3) do |node| node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr41) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr42) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr43) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end end defGroup('Source5', property.source3) do |node| node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr51) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr52) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end node.addApplication("ping_app") do |app| app.setProperty('dest_addr', property.sinkaddr53) app.setProperty('count', 30) app.setProperty('interval', 1) app.measure('myping', :samples => 1) end end onEvent(:ALL_UP_AND_INSTALLED) do |event| info "Starting the ping" allGroups.startApplications wait 5 info "Stopping the ping" allGroups.stopApplications Experiment.done end }}} == 4. Running Actual Experiment == 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. [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/otg_nmetrics.png?format=raw)]] The one we use for this tutorial is shown below. '''In !LabWiki''' [[BR]] step4-otg_nmetrics.rb {{{ defProperty('theSender','nodeB','ID of sender node') defProperty('theReceiver1', 'nodeE', "ID of receiver node") defProperty('theReceiver2', 'nodeA', "ID of receiver node") defProperty('theReceiver3', 'nodeD', "ID of receiver node") defProperty('packetsize', 128, "Packet size (byte) from the sender node") defProperty('bitrate', 2048, "Bitrate (bit/s) from the sender node") defProperty('runtime', 40, "Time in second for the experiment is to run") defGroup('Sender',property.theSender) do |node| options = { 'sample-interval' => 2 } node.addPrototype("system_monitor", options) node.addApplication("test:app:otg2") do |app| app.setProperty('udp:local_host', '192.168.2.10') app.setProperty('udp:dst_host', '192.168.6.14') app.setProperty('udp:dst_port', 3000) app.setProperty('cbr:size', property.packetsize) app.setProperty('cbr:rate', property.bitrate * 2) app.measure('udp_out', :samples => 1) end node.addApplication("test:app:otg2") do |app| app.setProperty('udp:local_host', '192.168.4.10') app.setProperty('udp:dst_host', '192.168.4.11') app.setProperty('udp:dst_port', 3000) app.setProperty('cbr:size', property.packetsize) app.setProperty('cbr:rate', property.bitrate * 2) app.measure('udp_out', :samples => 1) end node.addApplication("test:app:otg2") do |app| app.setProperty('udp:local_host', '192.168.1.10') app.setProperty('udp:dst_host', '192.168.1.13') app.setProperty('udp:dst_port', 3000) app.setProperty('cbr:size', property.packetsize) app.setProperty('cbr:rate', property.bitrate * 2) app.measure('udp_out', :samples => 1) end end defGroup('Receiver1',property.theReceiver1) do |node| options = { 'sample-interval' => 2 } node.addPrototype("system_monitor", options) node.addApplication("test:app:otr2") do |app| app.setProperty('udp:local_host', '192.168.6.14') app.setProperty('udp:local_port', 3000) app.measure('udp_in', :samples => 1) end end defGroup('Receiver2',property.theReceiver2) do |node| options = { 'sample-interval' => 2 } node.addPrototype("system_monitor", options) node.addApplication("test:app:otr2") do |app| app.setProperty('udp:local_host', '192.168.4.11') app.setProperty('udp:local_port', 3000) app.measure('udp_in', :samples => 1) end end defGroup('Receiver3',property.theReceiver3) do |node| options = { 'sample-interval' => 2 } node.addPrototype("system_monitor", options) node.addApplication("test:app:otr2") do |app| app.setProperty('udp:local_host', '192.168.1.13') app.setProperty('udp:local_port', 3000) app.measure('udp_in', :samples => 1) end end onEvent(:ALL_UP_AND_INSTALLED) do |event| info "starting" wait 5 allGroups.exec("ln -s /usr/local/bin/otr2 /usr/bin/otr2") allGroups.exec("ln -s /usr/local/bin/otg2 /usr/bin/otg2") allGroups.exec("ln -s /usr/local/bin/oml2-nmetrics /usr/bin/oml2-nmetrics") allGroups.startApplications info "All applications started..." wait property.runtime / 4 property.packetsize = 256 wait property.runtime / 4 property.packetsize = 512 wait property.runtime / 4 property.packetsize = 1024 wait property.runtime / 4 allGroups.stopApplications info "All applications stopped." Experiment.done end }}} [[BR]] [[BR]] == 5. !LabWiki == !LabWiki is a tool which provides a user-friendly interface to visualize your experiment. To know more about !LabWiki please visit [https://github.com/mytestbed/labwiki LabWiki] [[BR]] !LabWiki can be used to Plan, Prepare and Run your Experiment.[[BR]] === 5.1 Login using OpenID === If you are logged in to the GENI Portal you will be logged in to !LabWiki automatically when you click Login. [[BR]] '''Otherwise please enter the same username and password you use for the GENI Portal'''[[BR]] There is a link to !LabWiki now available through the GENI Portal or you can click [http://emmy9.casa.umass.edu:4400 here] to use !LabWiki [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_OpenID.png?format=raw)]] '''Figure (1)''' '''Send your information. This allows !LabWiki to use the GENI Portal ID to log you in to !LabWiki.'''[[BR]] [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_sendinfo.png?format=raw)]] '''Figure (2)''' === 5.2 Plan === After you have successfully been signed in you will be able to see a screen like the one below. [[BR]] [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_1.png?format=raw)]] '''Figure (3)''' The left column could contain the steps to run the experiment or general information about the experiment.[[BR]] The scripts are written using a simple [http://daringfireball.net/projects/markdown/syntax markdown scripts]. [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_2.png?format=raw)]] '''Figure (4)''' === 5.3 Prepare === In the Prepare column, you can select the experiment that you want to execute. In this column you will also be able to edit your experiment script.[[BR]] [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_4.png?format=raw)]] '''Figure (5)''' After editing, click on the save icon at the top of the column to save your script. [[BR]] Next, click and drag the icon at the top left corner over to the right column Execute.[[BR]] === 5.4 Execute === Here, you can start your experiment and Visualise it. In the name tab, type in the name you wish to give the experiment. Your name should only consist of alphanumeric characters. Only '_' is allowed as a special character.[[BR]] ==== 5.4.1 Add a Context ==== If you do not want to create a new context, skip this step. [[BR]] At the top-right corner there is a button called 'Add Context'. This allows you to create an Experiment context which can be useful when you want to store related experiments in the same folder with associated metadata. This Context can then be browsed using the iRODs web interface. [[BR]] Give the context a name, as shown below and click on 'Save': [[BR]] [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_15.png?format=raw)]] '''Figure (6)''' ==== 5.4.2 Run Experiment ==== Give your task a name. Select the Project, Experiment Context and Slice from the drop down menu on the screen.[[BR]] Then scroll towards the bottom of this column and under the tab named Graph, type 'true'.This enables the graph view on your execute column.[[BR]] Once the experiment starts running you will be able to scroll down and view the graph.[[BR]] [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_16.png?format=raw)]] '''Figure (7)''' Click on 'Start Experiment' at the bottom of the screen. [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_19.png?format=raw)]] '''Figure (8)''' After a couple of seconds, you can see the graph at the bottom of the screen.[[BR]] You can click and drag it to the Plan screen just above Figure 1. This will display the graph along with the experiment description. This graph is also dynamic.[[BR]] This allows you to add any comments or details about the experiment results.[[BR]] Similarly, Experiments 2 and 3 can be run using the same procedure. Experiment 2 does not have a graph.[[BR]] At any point during the run of your experiment or at the end of your experiment, click on Dump at the top of the Execute column to save your experiment data in iRODs.[[BR]] Each time you click on Dump a new .sql file will be created in your measurementData folder in iRODs. [[Image(http://groups.geni.net/geni/attachment/wiki/GEC17Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Execute/Labwiki_12.png?format=raw)]] '''Figure(9)''' Once you have your slice up and running you can visualize any experiment using !LabWiki. ==== 5.4.3 View results in iDrop ==== Any measurement related data will be stored on iRODs under the folder named with your experiment context. You can use iDrop to download your measurement data in .sql format. [[Image(idrop2.png)]] As you can see on the right pane at the top, there is a button that says "Download". Browse to the desired project, Experiment Context and click on this to save your measurement data to your local system.[[BR] [http://groups.geni.net/geni/wiki/GEC18Agenda/GettingStartedWithGENI_III_GIMI/Procedure/Finish Next Step: Finish Experiment] [http://groups.geni.net/geni/wiki/GEC18Agenda/GettingStartedWithGENI_III_GIMI/Procedure/DesignSetup Back to Design/Setup]