Changes between Initial Version and Version 1 of Documentation/hAndroid/OMF


Ignore:
Timestamp:
Aug 6, 2011, 1:57:33 AM (13 years ago)
Author:
choochootrain
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/hAndroid/OMF

    v1 v1  
     1= OMF on Android =
     2
     3== 0. Setup device ==
     4
     5In order to run OMF Resource Controller on an Android device, we need a Ruby interpreter.
     6
     7We will use [http://code.google.com/p/android-scripting/ Scripting Layer for Android (SL4A).] Go to Downloads and download the latest revision of sl4a.apk.
     8
     9You can install this app via adb:
     10{{{
     11adb install sl4a.apk
     12}}}
     13or you can copy the file onto your device's SD card and navigate to it with a file manager such as Astro.
     14
     15Note: You will need to have enabled installation of non-Market apps via Setting > Applications > Unknown Sources.
     16
     17SL4A only includes the Shell interpreter, but we need Ruby functionality. Fortunately, SL4A supports a JRuby interpreter. JRuby is an implementation of Ruby on the Java Virtual Machine. The majority of your code and gems will run properly, with the exception of native gems written in C, such as the built in Yaml parser.
     18
     19To install the JRuby interpreter, press Menu and then View > Interpreters. From here you can see all installed interpreters. To add a new one, press Menu and then Add > JRuby. The .apk should automatically download. Install and open it. Press install, and it will download the necessary libraries to start the JRuby interpreter from SL4A.
     20
     21== 1. Get OMF source code ==
     22
     23Now we need the OMF source code to run.
     24{{{
     25git clone git://git.mytestbed.net/omf.git -b release-5.3
     26}}}
     27
     28We will only work with omf-common and omf-resctl.
     29
     30Copy the root directory that holds omf-common and omf-resctl to sl4a/scripts on the device's SD card. You should now be able to view the OMF files in SL4A.
     31
     32== 2. Bootstrap OMF ==
     33
     34If you just try to start the resource controller by running omf-resctl/ruby/omf-resctl/nodeAgent.rb, you will run into errors regarding the load path. This is because the resource controller is supposed to be started via omf-resctl/sbin/omf-resctl:
     35{{{
     36#!/bin/sh
     37#...
     38
     39export LANG=c
     40
     41VER=5.3
     42APP=omf-resctl/nodeAgent.rb
     43if [ -e /usr/share/omf-resctl-$VER/$APP ]; then
     44   PDIR=/usr/share/omf-resctl-$VER
     45else
     46   echo "Cannot find the ruby module location ($APP)."
     47   exit 1;
     48fi
     49exec ruby1.8 -I$PDIR -I/usr/share/omf-common-$VER $PDIR/$APP $*
     50}}}
     51
     52So nodeAgent.rb is run with ruby1.8 with the 2 -I flags. These -I flags load the dependencies into Ruby before nodeAgent.rb is run. Since we are working with an app that does not support command line arguments, we will have to implement a workaround.
     53
     54In the root directory of the OMF source code, create a file called bootstrap.rb and copy this in:
     55{{{
     56APP_DIR = File.expand_path File.dirname(__FILE__)
     57#GEM_DIR = File.join(APP_DIR, 'vendor', 'gems')
     58RESCTL_DIR = File.join(APP_DIR, 'omf-resctl', 'ruby')
     59COMMON_DIR = File.join(APP_DIR, 'omf-common', 'ruby')
     60NODE_PATH = File.join(RESCTL_DIR,'omf-resctl', 'nodeAgent.rb')
     61
     62#Dir.entries(GEM_DIR).each do |dir|
     63#  $LOAD_PATH << File.join(GEM_DIR, dir, 'lib')
     64#end
     65
     66$LOAD_PATH << RESCTL_DIR
     67$LOAD_PATH << COMMON_DIR
     68puts $LOAD_PATH
     69
     70puts NODE_PATH
     71
     72require NODE_PATH
     73}}}
     74
     75This script is in essence a Ruby translation of the shell script above that loads all Ruby dependencies (RESCTL_DIR and COMMON_DIR) to the LOAD_PATH variable before running nodeAgent.rb (NODE_PATH).
     76
     77== 3. Load networking drivers ==
     78
     79In order to properly retreve data from the device, you need to use the corresponding driver for the wireless chipsets. nodeAgent does this by running lspci, which does not work on Android.
     80
     81Comment out the call to lspci from line 412-425 and 428-447 in omf-resctl\ruby\omf-resctl\omf_agent\nodeAgent.rb, leaving the Intel card portion uncommented
     82{{{
     83require 'omf-resctl/omf_driver/intel'
     84MObject.info "Have Intel cards"
     85AgentCommands::DEV_MAPPINGS['net/w0'] = IntelDevice.new('net/w0', 'eth2')
     86AgentCommands::DEV_MAPPINGS['net/w1'] = IntelDevice.new('net/w1', 'eth3')
     87}}}
     88
     89The Intel driver is not completely compatible with the wireless chipsets on the device, but it works.
     90
     91== 4. Vendorize Gems ==
     92OMF relies on several gems that we do not have on the SD card.
     93
     94In order to continue, we need the log4r, xmpp4r, and RbYAML gems. On a computer with Ruby and RubyGems installed, type
     95{{{
     96gem install log4r
     97gem install xmpp4r
     98gem install RbYAML
     99}}}
     100to install the gems. SL4A doesnt support RubyGems, so we will have to vendorize them.
     101{{{
     102mkdir vendor/gems
     103gem unpack log4r --target=vendor/gems
     104gem unpack xmpp4r --target=vendor/gems
     105gem unpack RbYAML --target=vendor/gems
     106}}}
     107and then place the /vendor directory in the root directory of OMF on the device's SD card.
     108
     109Uncomment the 4 lines in bootstrap.rb - They check the vendor/gems folder and manually load the gems.
     110
     111OMF uses .yaml configuration files, but the default Yaml parser in Ruby is written in C, and therefore will not work on JRuby. We will use RbYAML instead. Replace line 358-359 of omf-resctl\ruby\omf-resctl\omf_agent\nodeAgent.rb:
     112{{{
     113require 'yaml'
     114h = YAML::load_file(@configFile)
     115}}}
     116with RbYAML:
     117{{{
     118require 'rbyaml'
     119temp_h = RbYAML::load_file(@configFile)
     120h = symbolize(temp_h)
     121}}}
     122and add the symbolize private method after line 386:
     123{{{
     124def symbolize (hash)
     125  if hash.class == Hash
     126    newHash = {}
     127      hash.each do |k, v|
     128        newHash[k.gsub(":", "").to_sym] = symbolize(v)
     129      end
     130    return newHash
     131  else
     132    return hash
     133  end
     134end
     135}}}
     136This is necessary because the native Yaml parser returns a hash with symbols for keys, and RbYAML returns a hash with strings as keys. We recursively copy the data into a new hash and convert the key from a string to symbol.
     137
     138== 5. Configure node ==
     139Resource Controller should be running now, you need to configure it accordingly.