-
Notifications
You must be signed in to change notification settings - Fork 1
Client Side Tutorial
- Read the OEDL introcution on mytestbed.net.
- Install the OMF experiment controller gem via console:
gem install omf_ec --no-ri --no-rdoc
- Configure the experiment controller for your needs:
- initialize the configuration:
omf_ec initconfig
- customize the config file:
~/.config/omf_ec.yml
Note: Read the OMF installation tutorial for further information.
Note 2: There are many different message types you'll receive on the client side. A detailed overview is given in the Message Documentation.
In this section you'll learn how to write a simple OMF experiment description using the wise_omf gem.
-
Install the wise_omf gem:
gem install wise_omf
-
Create a configuration file containing information about your reservation on the testbed (
reservation.yml
):--- :secretReservationKeys: - :nodeUrnPrefix: "urn:wisebed:uzl1:" :key: "abc..." - :nodeUrnPrefix: "<other prefix>" :key: "<other secret reservation key>" :nodeUrns: - "urn:wisebed:uzl1:0x0002" - "urn:wisebed:uzl1:0x0003" - "<other node urn>"
The section secretReservationKeys contains the information about reservations on different testbeds while the nodeUrns section contains a list of all nodes in your reservation.
-
Write the experiment description (
experiment_description.rb
): -
require some gems:
require 'wise_omf/client' require 'yaml' require 'base64'
-
load the configuration:
reservation = YAML.load_file('./reservation.yml')
-
Initialize the reservation manager of the wise_omf helper gem.
The manager is a factory which initializes
WiseGroup
objects encapsulating OMF groups containing node resources. During the initialization theReservationManager
creates oneOmfEc::Group
foreach node urn as well as one group for all nodes together. These groups can be used to configure nodes or a set of nodes or to request information from the nodes. Read the documentation of theReservationManager
on rubydoc.infoWiseOMF::Client::ReservationManager.init(reservation, reservation[:nodeUrns])
-
optional: Set a default callback for events comming from some of the node groups:
WiseOMF::Client::ReservationManager.allNodesGroup.default_callback = lambda { |msg| info "Default Callback: #{msg.to_yaml}" # Do somthing with the message }
Note: The code example registers a default callback on the group containing all nodes of the reservation. Of course it is possible to add a default callback to any other node group that can be requested from the
ReservationManager
. -
Wait for the OMF event
ALL_NODES_UP
. This is the real starting point of your experiment:onEvent :ALL_NODES_UP do # Write the experiment as described in the next section end
At this point you have configured the OMF experiment controller and the experiment initialization is finished. All nodes are up and you are able to communicate with them.
The example in this section will teach you how to talk to a subset of all nodes in your reservation. For this purpose you'll need to create a new group dynamically by asking the ReservationManager
to create it.
-
Create a group for some nodes in your reservation:
WiseOMF::Client::ReservationManager.createGroupForNodes(%w(<node:urn:1> <node:urn:2> ...)) { |group| # When this callback is called, the group was created sucessfully and you could talk to it }
-
Talk to the node group in the creation callback. Ask the group whether all nodes are connected to the testbed:
group.connected { |properties| # You'll get an array of responses (one for each node in your group). # Check if all nodes are connected if properties.responses.all? { |response| response.statusCode == 1 } # All nodes are connected. Now you can work with the nodes. end }
-
Working with node groups: flashing an image onto all nodes of the group
Note: Though we are talking of node groups or just groups in this tutorial, all operations are the same when talking to a single node hence you are communicating with a group containing the single node.
-
Load the binary image from your disk:
flash_image = File.read('<path/to/your/image.bin>')
-
Encode the image. When flashing an image onto nodes, the testbed expects the binary image to be Base 64 encoded.
encoded_image = Base64.encode64(flash_image)
-
Send the flash command to the group and handle responses and progress messages from the testbed:
group.set_image(encoded_image) { |properties| if properties.type.to_sym.eql? :progress # the message is a progress message of a single node in the group info "Progress of #{properties.nodeUrn}: #{properties.progress}%" elsif properties.type.to_sym.eql? :response # the message is a response telling us, that the flashing task was completed (or failed) # this message contains on response for every node in the group info "Finished with response: #{properties.responses.to_yaml}" # Make sure that further responses to the flash request are ignored: group.delete_callback(properties.requestId) # Continue with the experiment ... end }
Note: It's recommended to put nodes that should be flashed with the same image into a group as shown in this example. This approach has some advantages as opposed to flashing every node on its own. When sending the flash request to a group of nodes, the image is only transmitted once and the testbed handles the distribution of the image. This is faster and cheaper than sending the same image multiple times.
Note 2: Your callback will be called for every progress message of every node in your group.
-
optional: continue with the experiment:
At this step, your own image was flashed onto all nodes of the group. Now you should be able to communicate with the nodes by sending messages and receiving responses/ messages from the nodes.
-
After finishing your experiment, it's good to call the
done
-Methods of theReservationManager
and theOmfEc::Experiment
to unsubscribe from topics and free resources:WiseOMF::Client::ReservationManager.done OmfEc::Experiment.done
require 'wise_omf/client'
require 'yaml'
require 'base64'
reservation = YAML.load_file('./reservation.yml')
WiseOMF::Client::ReservationManager.init(reservation, reservation[:nodeUrns])
WiseOMF::Client::ReservationManager.allNodesGroup.default_callback = lambda { |msg|
info "Default Callback: #{msg.to_yaml}"
# Do somthing with the message
}
onEvent :ALL_NODES_UP do
WiseOMF::Client::ReservationManager.createGroupForNodes(%w(<node:urn:1> <node:urn:2> ...)) { |group|
group.connected { |properties|
# You'll get an array of responses (one for each node in your group).
# Check if all nodes are connected
if properties.responses.all? { |response| response.statusCode == 1 }
# All nodes are connected. Now you can work with the nodes.
flash_image = File.read('<path/to/your/image.bin>')
encoded_image = Base64.encode64(flash_image)
group.set_image(encoded_image) { |properties|
if properties.type.to_sym.eql? :progress
# the message is a progress message of a single node in the group
info "Progress of #{properties.nodeUrn}: #{properties.progress}%"
elsif properties.type.to_sym.eql? :response
# the message is a response telling us, that the flashing task was completed (or failed)
# this message contains on response for every node in the group
info "Finished with response: #{properties.responses.to_yaml}"
# Make sure that further responses to the flash request are ignored:
group.delete_callback(properties.requestId)
# Continue with the experiment ...
WiseOMF::Client::ReservationManager.done
OmfEc::Experiment.done
end
}
end
}
}
end
At this step you have writen an experiment description as described in the last two sections. Let's execute the experiment via your shell:
omf_ec exec experiment_description.rb