Changes between Version 15 and Version 16 of GEC19Agenda/GIMI/Procedure/Execute


Ignore:
Timestamp:
03/18/14 12:42:49 (10 years ago)
Author:
divyashri.bhat@gmail.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GEC19Agenda/GIMI/Procedure/Execute

    v15 v16  
    265265
    266266[[Image(markdown.png, 80%)]]
     267
     268{{{
     269#Example: Writing an OML Layer 2 Ping Application (aka pingPlus)#
     270
     271##Prerequisites##
     272Setup your experiment as shown here with the pingPlus package [link](http://www.gpolab.bbn.com/experiment-support/gec17/pingPlus/pingPlus_v3.tar.gz):
     273http://groups.geni.net/geni/wiki/Tutorials/ICDCS2013/GettingStartedWithGENI_I/Procedure/DesignSetup
     274
     275##Results##
     276
     277![](_)   
     278__Figure 1__. My layer 2 Ping Application
     279
     280
     281##Write your Application##
     282
     283To write a omlified ping application, we can firstly parse output to get Measurement points:
     284
     285        def process_output(row)
     286          if not (parse= /RQ:'(?<pktsnt1>\d*)\+(?<pktsnt2>\d*)' to (?<host>[a-f0-9:]*)/.match(row)).nil?
     287          puts "ReturnQual #{parse[:pktsnt1]}\n"
     288          MPrt.inject(parse[:pktsnt1], parse[:pktsnt2],parse[:host])
     289         
     290          elsif not (parse= /RL:(?<numofpkt1>\d*)\+(?<numofpkt2>\d*)=(?<totpktrec>\d*) from (?<dest_hw_addr>[a-f0-9:]*)/.match(row)).nil?
     291          puts "ReturnLength\n"
     292          p parse
     293          p MPrl.inject(parse[:numofpkt1],parse[:numofpkt2],parse[:totpktrec],parse[:dest_hw_addr])
     294         
     295          elsif not (parse = /RTT = (?<rtt>[0-9.]*)/.match(row)).nil?
     296          puts "RoundTripTime #{parse[:rtt]}\n"
     297          p parse
     298          p MPrtt.inject(parse[:rtt])
     299          end
     300        end
     301
     302Then write the whole application script:
     303
     304        #!/usr/bin/ruby1.9.1
     305        require 'rubygems'
     306        require 'oml4r'
     307       
     308        class MPrt < OML4R::MPBase
     309           name :pingrt
     310           param :pktsnt1, :type => :uint64
     311           param :pktsnt2, :type => :uint64
     312           param :host, :type => :string
     313        end
     314       
     315        class MPrl < OML4R::MPBase
     316           name :pingrl
     317           param :totpktrec, :type => :uint64
     318           param :numofpkt1, :type => :uint64
     319           param :numofpkt2, :type => :uint64
     320           param :dest_hw_addr, :type => :string
     321        end
     322       
     323        class MPrtt < OML4R::MPBase
     324           name :pingrtt
     325           param :rtt, :type => :double
     326        end
     327       
     328        class Pingl2Wrapper
     329       
     330          def initialize(args)
     331             @addr = nil
     332             @if_num = ''
     333             @eth = nil
     334             @verbose = true
     335             @numeric = ''
     336             
     337             leftover = OML4R::init(args, :appName => 'pingl2') do |argParser|
     338               argParser.banner = "Runs layer 2 ping and reports measurements via OML\n\n"
     339               argParser.on("-a" , "--dest_hw_addr ADDRESS", "Hardware address to ping (the -a switch is optional)"){ |address| @addr = address.to_s() }
     340               argParser.on("-i","--interface IFNUM","Interface number"){ |if_num| @if_num ="#{if_num.to_i()}" }
     341               argParser.on("-e", "--eth ETHTYPE","Ethernet Type") { |ethtype| @eth = ethtype.to_s() }
     342               argParser.on("-c","--count NUMBER","Number of pings (default: infinite)"){ |count| @count = "#{count.to_i()}"}
     343               argParser.on("-q", "--no-quiet ","Don't show layer 2 ping output on console"){ @verbose = false }
     344               argParser.on("-n", "--[no]-numeric ", "No attempt twill be made to look up symbolic names for host addresses"){ @numeric ='-n' }
     345            end
     346           
     347            if @addr.nil?
     348              if leftover.length > 0
     349                @addr = leftover [0]
     350              else
     351                raise "You did not specify an address to ping!"
     352              end
     353            end
     354           
     355        end
     356       
     357        def process_output(row)
     358          if not (parse= /RQ:'(?<pktsnt1>\d*)\+(?<pktsnt2>\d*)' to (?<host>[a-f0-9:]*)/.match(row)).nil?
     359          puts "ReturnQual #{parse[:pktsnt1]}\n"
     360          MPrt.inject(parse[:pktsnt1], parse[:pktsnt2],parse[:host])
     361         
     362          elsif not (parse= /RL:(?<numofpkt1>\d*)\+(?<numofpkt2>\d*)=(?<totpktrec>\d*) from (?<dest_hw_addr>[a-f0-9:]*)/.match(row)).nil?
     363          puts "ReturnLength\n"
     364          p parse
     365          p MPrl.inject(parse[:numofpkt1],parse[:numofpkt2],parse[:totpktrec],parse[:dest_hw_addr])
     366         
     367          elsif not (parse = /RTT = (?<rtt>[0-9.]*)/.match(row)).nil?
     368          puts "RoundTripTime #{parse[:rtt]}\n"
     369          p parse
     370          p MPrtt.inject(parse[:rtt])
     371          end
     372        end
     373         
     374        def pingl2()
     375           @pingio = IO.popen("/bin/pingPlus #{@addr} #{@eth} #{@if_num} #{@count}")
     376           while true
     377            row = @pingio.readline
     378            puts row if @verbose
     379            process_output(row)
     380            end
     381        end
     382       
     383        def start()
     384            return if not @pingio.nil?
     385           
     386            # handle for OMF's exit command
     387            a = Thread.new do
     388              $stdin.each do |line|
     389            if /^exit/ =~ line
     390              Process.kill("INT",0)   
     391            end
     392              end
     393            end
     394           
     395            # Handle Ctrl+C and OMF's SIGTERM
     396            Signal.trap("INT", stop)
     397            Signal.trap("TERM", stop)
     398           
     399            begin
     400              pingl2
     401            rescue EOFError
     402           
     403            end
     404        end
     405       
     406        def stop()
     407           return if @pingio.nil?
     408           # Kill the ping process, which will result in EOFError from ping()
     409           Process.kill("INT", @pingio.pid)
     410        end
     411       
     412        end
     413        begin
     414          $stderr.puts "INFO\tpingl2 2.11.0\n"
     415          app = Pingl2Wrapper.new(ARGV)
     416          app.start()
     417          sleep 1
     418        rescue Interrupt
     419        rescue Exception => ex
     420           $stderr.puts "Error\t#{ex}\n"
     421        end
     422       
     423       
     424       
     425        # Local Variables:
     426        # mode:ruby 
     427        # End:
     428        # vim: ft=ruby:sw=2
     429
     430##Test your Application##
     431Finally write OEDL Script to test application:
     432
     433        defProperty('source1', "client-testpingplus", "ID of a resource")
     434        #defProperty('source2', "ig-utah-testBBN", "ID of a resource")
     435        #defProperty('source3', "nodeC-createexoimage", "ID of a resource")
     436        #defProperty('source4', "nodeD-createexoimage", "ID of a resource")
     437        #defProperty('source5', "nodeE-createexoimage", "ID of a resource")
     438        defProperty('graph', true, "Display graph or not")
     439       
     440       
     441        defProperty('sinkaddr11', 'fe:16:3e:00:74:38', "Ping destination address")
     442        defProperty('eth11','eth1',"Output Eth interface")
     443        defProperty('sinkaddr12', 'fe:16:3e:00:74:38', "Ping destination address")
     444       
     445        #defProperty('sinkaddr11', '192.168.6.10', "Ping destination address")
     446        #defProperty('sinkaddr12', '192.168.5.12', "Ping destination address")
     447       
     448        #defProperty('sinkaddr21', '192.168.4.11', "Ping destination address")
     449        #defProperty('sinkaddr22', '192.168.2.12', "Ping destination address")
     450        #defProperty('sinkaddr23', '192.168.1.13', "Ping destination address")
     451       
     452        #defProperty('sinkaddr31', '192.168.5.11', "Ping destination address")
     453        #defProperty('sinkaddr32', '192.168.2.10', "Ping destination address")
     454        #defProperty('sinkaddr33', '192.168.3.13', "Ping destination address")
     455        #defProperty('sinkaddr34', '192.168.6.14', "Ping destination address")
     456       
     457        #defProperty('sinkaddr41', '192.168.1.10', "Ping destination address")
     458        #defProperty('sinkaddr42', '192.168.3.12', "Ping destination address")
     459       
     460        #defProperty('sinkaddr51', '192.168.6.12', "Ping destination address")
     461       
     462        defApplication('ping') do |app|
     463          app.description = 'Simple Definition for the pingl2 application'
     464          # Define the path to the binary executable for this application
     465          app.binary_path = '/usr/local/bin/pingl2'
     466          # Define the configurable parameters for this application
     467          # For example if target is set to foo.com and count is set to 2, then the
     468          # application will be started with the command line:
     469          # /usr/bin/ping-oml2 -a foo.com -c 2
     470          app.defProperty('target', 'Address to ping', '-a', {:type => :string})
     471          app.defProperty('count', 'Number of times to ping', '-c', {:type => :integer})
     472          app.defProperty('if_num', 'interface number', '-i', {:type => :integer})
     473          app.defProperty('eth', 'Ethernet Type', '-e', {:type => :string})
     474          # Define the OML2 measurement point that this application provides.
     475          # Here we have only one measurement point (MP) named 'ping'. Each measurement
     476          # sample from this MP will be composed of a 4-tuples (addr,ttl,rtt,rtt_unit)
     477          app.defMeasurement('ping') do |m|
     478            m.defMetric('hw_dest_addr',:string)
     479            m.defMetric('rtt',:double)
     480          end
     481        end
     482        defGroup('Source1', property.source1) do |node|
     483          node.addApplication("ping") do |app|
     484            app.setProperty('target', property.sinkaddr11)
     485            app.setProperty('count', 30)
     486            app.setProperty('if_num', 10002)
     487            app.setProperty('eth',property.eth11)
     488            app.measure('ping', :samples => 1)
     489          end
     490        end
     491       
     492       
     493        #defGroup('Source2', property.source2) do |node|
     494         # node.addApplication("ping") do |app|
     495          #  app.setProperty('target', property.sinkaddr11)
     496           # app.setProperty('count', 30)
     497            #app.setProperty('interval', 1)
     498           # app.measure('ping', :samples => 1)
     499          #end
     500        #end
     501       
     502       
     503        onEvent(:ALL_UP_AND_INSTALLED) do |event|
     504          info "Starting the ping"
     505          after 5 do
     506            allGroups.startApplications
     507          end
     508          after 70 do
     509            info "Stopping the ping"
     510            allGroups.stopApplications
     511            Experiment.done
     512          end
     513        end
     514       
     515        defGraph 'RTT' do |g|
     516          g.ms('ping').select(:oml_seq, :hw_dest_addr, :rtt)
     517          g.caption "RTT of received packets."
     518          g.type 'line_chart3'
     519          g.mapping :x_axis => :oml_seq, :y_axis => :rtt, :group_by => :hw_dest_addr
     520          g.xaxis :legend => 'oml_seq'
     521          g.yaxis :legend => 'rtt', :ticks => {:format => 's'}
     522        end
     523
     524
     525
     526##Troubleshooting##
     527To debug and test application manually on RC (resource controller):
     528
     529Manually run the command and store data on any location in the RC (~/testpingnow.out)
     530
     531        env -i /usr/local/bin/pingl2 -a fe:16:3e:00:74:38 -c 5 -i 10002 -e eth1 --oml-id pingl2 --oml-domain tetspingl2 --oml-collect file:/home/dbhat/testpingnow.out
     532
     533Contents of ~/testpingnow.out:
     534
     535        protocol: 4
     536        content: text
     537        domain: tetspingl2
     538        start-time: 1387350654
     539        sender-id: pingl2
     540        app-name: pingl2
     541        schema: 0 _experiment_metadata subject:string key:string value:string
     542        schema: 1 pingl2_pingrt pktsnt1:integer pktsnt2:integer host:string
     543        schema: 2 pingl2_pingrl totpktrec:integer numofpkt1:integer numofpkt2:integer dest_hw_addr:string
     544        schema: 3 pingl2_pingrtt rtt:double
     545       
     546        0.008326062     1       1       8769    3486    fe:16:3e:0:74:38
     547        0.008561018     2       1       8769    3486    12255   fe:16:3e:0:74:38
     548        0.008747358     3       1       4.083984
     549        0.008879672     1       2       219     3026    fe:16:3e:0:74:38
     550        0.009011919     2       2       8769    3486    12255   fe:16:3e:0:74:38
     551        0.009165199     3       2       1.743896
     552       
     553}}}
    267554
    268555OEDL Script