omf_rc 6.0.0.pre.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +16 -0
- data/bin/omf_rc +64 -0
- data/config/omf_rc.yml +70 -0
- data/integration_test/omf_rc/resource_proxy/app_spec.rb +25 -0
- data/integration_test/omf_rc/resource_proxy/interface_spec.rb +26 -0
- data/integration_test/omf_rc/resource_proxy/mock_spec.rb +58 -0
- data/integration_test/omf_rc/resource_proxy/node_spec.rb +26 -0
- data/integration_test/omf_rc/resource_proxy/wifi_spec.rb +30 -0
- data/integration_test/test_helper.rb +5 -0
- data/lib/omf_rc/deferred_process.rb +20 -0
- data/lib/omf_rc/message_process_error.rb +11 -0
- data/lib/omf_rc/resource_factory.rb +74 -0
- data/lib/omf_rc/resource_proxy/abstract_resource.rb +257 -0
- data/lib/omf_rc/resource_proxy/interface.rb +48 -0
- data/lib/omf_rc/resource_proxy/mock.rb +16 -0
- data/lib/omf_rc/resource_proxy/node.rb +17 -0
- data/lib/omf_rc/resource_proxy/wifi.rb +8 -0
- data/lib/omf_rc/resource_proxy_dsl.rb +170 -0
- data/lib/omf_rc/util/iw.rb +22 -0
- data/lib/omf_rc/util/mock.rb +27 -0
- data/lib/omf_rc/util/mod.rb +23 -0
- data/lib/omf_rc/util/package.rb +17 -0
- data/lib/omf_rc/version.rb +3 -0
- data/lib/omf_rc.rb +6 -0
- data/omf_rc.gemspec +25 -0
- data/test/omf_rc/deferred_process_spec.rb +39 -0
- data/test/omf_rc/resource_factory_spec.rb +18 -0
- data/test/omf_rc/resource_proxy/abstract_resource_spec.rb +82 -0
- data/test/omf_rc/resource_proxy_dsl_spec.rb +43 -0
- data/test/test_helper.rb +11 -0
- metadata +128 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
|
4
|
+
task :default => :test
|
5
|
+
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.libs << 'test'
|
8
|
+
t.pattern = "test/**/*_spec.rb"
|
9
|
+
t.verbose = true
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::TestTask.new(:integration) do |t|
|
13
|
+
t.libs << 'integration_test'
|
14
|
+
t.pattern = "integration_test/**/*_spec.rb"
|
15
|
+
t.verbose = true
|
16
|
+
end
|
data/bin/omf_rc
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require 'omf_common'
|
5
|
+
require 'omf_rc'
|
6
|
+
require 'omf_rc/resource_factory'
|
7
|
+
$stdout.sync = true
|
8
|
+
|
9
|
+
options = {
|
10
|
+
uid: 'interlagos'
|
11
|
+
}
|
12
|
+
|
13
|
+
executable_name = File.basename($PROGRAM_NAME)
|
14
|
+
|
15
|
+
option_parser = OptionParser.new do |opts|
|
16
|
+
opts.banner = "usage: #{executable_name} [options]"
|
17
|
+
|
18
|
+
opts.on("-u USER", "Username") do |user|
|
19
|
+
options[:user] = user
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on("-p PASSWORD", "Password") do |password|
|
23
|
+
options[:password] = password
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on("-s SERVER", "XMPP server") do |server|
|
27
|
+
options[:server] = server
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("-n NODE", "PubSub node to create, also becomes the uid of the resource") do |node|
|
31
|
+
options[:uid] = node
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on("-d", "--debug", "Debug mode") do
|
35
|
+
options[:debug] = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
option_parser.parse!
|
41
|
+
rescue => e
|
42
|
+
puts e.message
|
43
|
+
puts ""
|
44
|
+
puts option_parser.help
|
45
|
+
exit(1)
|
46
|
+
end
|
47
|
+
|
48
|
+
unless options[:server] && options[:user] && options[:server]
|
49
|
+
puts option_parser.help
|
50
|
+
exit(1)
|
51
|
+
end
|
52
|
+
|
53
|
+
Logging.logger.root.level = :debug if options[:debug]
|
54
|
+
Blather.logger = logger
|
55
|
+
|
56
|
+
OmfRc::ResourceFactory.load_default_resource_proxies
|
57
|
+
|
58
|
+
EM.run do
|
59
|
+
node = OmfRc::ResourceFactory.new(:node, options)
|
60
|
+
node.connect
|
61
|
+
|
62
|
+
trap(:INT) { node.disconnect }
|
63
|
+
trap(:TERM) { node.disconnect }
|
64
|
+
end
|
data/config/omf_rc.yml
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# This is an example configuration for the Resource Controller at NICTA
|
2
|
+
#
|
3
|
+
# NOTE: use only 'spaces' to indent !
|
4
|
+
# ('tab' indents are not supported by the ruby yaml parser used to read this file)
|
5
|
+
#
|
6
|
+
---
|
7
|
+
:rcontroller:
|
8
|
+
# Communication settings
|
9
|
+
:communicator:
|
10
|
+
|
11
|
+
# Interface to the control network from which this resource can be
|
12
|
+
# controlled & managed
|
13
|
+
:control_if: 'control'
|
14
|
+
|
15
|
+
# set this to true or false if you want to enable or disable signature checks and message signing
|
16
|
+
:authenticate_messages: false
|
17
|
+
# your RSA/DSA SSH private key file
|
18
|
+
:private_key: '/etc/omf-resctl-5.4/id_rsa'
|
19
|
+
# directory holding the public keys of your OMF peers
|
20
|
+
:public_key_dir: '/etc/omf-resctl-5.4/peer_keys'
|
21
|
+
|
22
|
+
:type: 'xmpp'
|
23
|
+
:xmpp:
|
24
|
+
# Address of the PubSub server to use as gateway for PubSub communication
|
25
|
+
:pubsub_gateway: 'norbit.npc.nicta.com.au'
|
26
|
+
#:pubsub_port: 5222
|
27
|
+
# Address of the PubSub server which host the communication for my slice
|
28
|
+
# Leave this commented if the pubsub groups for this slice are hosted on
|
29
|
+
# the same server as the 'pubsub_gateway'
|
30
|
+
#:pubsub_domain: 10.0.0.200
|
31
|
+
# The following 'home_pubsub_user' and 'home_pubsub_pwd' are optional
|
32
|
+
# RC will create a unique user/pwd for itself if this is not provided
|
33
|
+
# In a typical OMF install, you should not uncomment these lines
|
34
|
+
# (do so only if you need to manually set user/password for
|
35
|
+
# your client to connect to your pubsub server)
|
36
|
+
#:pubsub_user: 'my_RC_name'
|
37
|
+
#:pubsub_pwd: 'my_RC_password'
|
38
|
+
# set this to "true" if you have a DNS SRV record pointing to the
|
39
|
+
# real pubsub server hostname
|
40
|
+
:pubsub_use_dnssrv: false
|
41
|
+
|
42
|
+
# Agent settings
|
43
|
+
:agent:
|
44
|
+
|
45
|
+
# Name (i.e. unique HRN ID) of this resource
|
46
|
+
# Or this could also be passed as a command line parameter "--name"
|
47
|
+
# This is either a fully defined string, e.g. "my_resource_name"
|
48
|
+
# Or a string for which some values will be replaced by the running RC,
|
49
|
+
# currently we support the values: %hostname%, %macaddr%, %fqdn%
|
50
|
+
# For example, if you use "some_prefix.%hostname%.some_suffix"
|
51
|
+
# Then if your hostname is 'node1', then your RC name will be
|
52
|
+
# 'some_prefix.node1.some_suffix'
|
53
|
+
# %macaddr% is replaced with the MAC address of the control interface
|
54
|
+
# %fqdn% is the fully qualified hostname (incl. domain part)
|
55
|
+
:name: 'omf.nicta.%hostname%'
|
56
|
+
|
57
|
+
# Name (i.e. unique HRN ID) of the slice to which this resource is assigned
|
58
|
+
:slice: default_slice
|
59
|
+
|
60
|
+
# shrink the filesystem size before saving an image
|
61
|
+
# grow the filesystem to match the disk size after loading an image
|
62
|
+
# enabling this may slow down load/save significantly
|
63
|
+
:resizefs: false
|
64
|
+
|
65
|
+
# Mote settings
|
66
|
+
# Uncomment and set the following parameters if this resource has
|
67
|
+
# a Mote device attached to it
|
68
|
+
#:mote:
|
69
|
+
#:moteport: /dev/ttyUSB0
|
70
|
+
#:motetype: telosb
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'omf_rc/resource_proxy'
|
3
|
+
|
4
|
+
include OmfRc::ResourceProxy
|
5
|
+
|
6
|
+
describe App do
|
7
|
+
before do
|
8
|
+
@resource = AbstractResource.new(properties: { pubsub: "mytestbed.net" })
|
9
|
+
@app1 = @resource.create(:type => 'app', :uid => 'zathura')
|
10
|
+
@app2 = @resource.create(:type => 'app', :uid => 'bob')
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "when configured with properties" do
|
14
|
+
it "must run the underline commands" do
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "when properties requested" do
|
19
|
+
it "must return an array with actual properties" do
|
20
|
+
@resource.request([:version], {:uid => 'zathura'}).first.version.must_match /[\d|\.|-]+/
|
21
|
+
@resource.request([:version], {:uid => 'bob'}).first.version.must_be_nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'omf_rc/resource_proxy'
|
3
|
+
|
4
|
+
include OmfRc::ResourceProxy
|
5
|
+
|
6
|
+
describe Interface do
|
7
|
+
before do
|
8
|
+
@resource = AbstractResource.new(properties: { pubsub: "mytestbed.net" })
|
9
|
+
@interface = @resource.create(:type => 'interface', :uid => 'eth0')
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "when configured with properties" do
|
13
|
+
it "must run the underline commands" do
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "when properties requested" do
|
18
|
+
it "must return an array with actual properties" do
|
19
|
+
@resource.request([:mac, :ip], {:type => 'interface'}).each do |interface|
|
20
|
+
interface.mac.must_match /([\da-fA-F]+:){5}[\da-fA-F]+/
|
21
|
+
interface.ip.must_match /([.\d]+\.){3}[.\d]+/
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'omf_rc/resource_factory'
|
3
|
+
|
4
|
+
include OmfRc::ResourceProxy
|
5
|
+
|
6
|
+
module OmfRc::Util::UMock
|
7
|
+
include OmfRc::ResourceProxyDSL
|
8
|
+
|
9
|
+
register_utility :u_mock
|
10
|
+
|
11
|
+
register_configure :very_important_property do
|
12
|
+
raise StandardError, 'We just did something very important, I need your attention'
|
13
|
+
end
|
14
|
+
|
15
|
+
register_request :very_important_property do
|
16
|
+
"Very important property's value"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module OmfRc::ResourceProxy::Mock
|
21
|
+
include OmfRc::ResourceProxyDSL
|
22
|
+
|
23
|
+
register_proxy :mock
|
24
|
+
|
25
|
+
utility :u_mock
|
26
|
+
|
27
|
+
register_bootstrap do
|
28
|
+
logger.debug 'I am starting up, but have nothing to do there'
|
29
|
+
end
|
30
|
+
|
31
|
+
register_cleanup do
|
32
|
+
logger.debug 'I am shutting down, but have nothing to do there'
|
33
|
+
end
|
34
|
+
|
35
|
+
def test
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Mock do
|
40
|
+
before do
|
41
|
+
@resource = OmfRc::ResourceFactory.new(:mock, :uid => 'suzuka', :properties => {:mock_property => "test"})
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "when child resource with a known type" do
|
45
|
+
it "must load methods from related module correctly" do
|
46
|
+
@resource.create(:mock, uid: 'mock') do |mock|
|
47
|
+
mock.must_respond_to :test
|
48
|
+
mock.must_respond_to :configure_very_important_property
|
49
|
+
mock.must_respond_to :request_very_important_property
|
50
|
+
proc { mock.configure_very_important_property('test') }.must_raise StandardError
|
51
|
+
mock.request_very_important_property do |value|
|
52
|
+
value.must_equal "Very important property's value"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'omf_rc/resource_proxy'
|
3
|
+
|
4
|
+
include OmfRc::ResourceProxy
|
5
|
+
|
6
|
+
describe Node do
|
7
|
+
before do
|
8
|
+
@resource = AbstractResource.new(properties: { pubsub: "mytestbed.net" })
|
9
|
+
@node = @resource.create(:type => 'node', :uid => 'monaco')
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "when configured with properties" do
|
13
|
+
it "must run the underline commands" do
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "when properties requested" do
|
18
|
+
it "must return an array with actual properties" do
|
19
|
+
@resource.request([:devices], {:uid => 'monaco'}).first.devices.each do |device|
|
20
|
+
device.type.wont_be_nil
|
21
|
+
device.name.wont_be_nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'omf_rc/resource_proxy'
|
3
|
+
|
4
|
+
include OmfRc::ResourceProxy
|
5
|
+
|
6
|
+
describe Wifi do
|
7
|
+
before do
|
8
|
+
@resource = AbstractResource.new(properties: { pubsub: "mytestbed.net" })
|
9
|
+
@wifi = @resource.create(:type => 'wifi', :uid => 'wlan0')
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "when configured with properties" do
|
13
|
+
it "must run the underline commands" do
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "when properties requested" do
|
18
|
+
it "must return an array with actual properties" do
|
19
|
+
@resource.request([:ssid, :freq, :rx, :tx, :signal, :tx_bitrate], {:type => 'wifi'}).each do |wifi|
|
20
|
+
wifi.ssid.wont_be_nil
|
21
|
+
wifi.freq.wont_be_nil
|
22
|
+
wifi.rx.wont_be_nil
|
23
|
+
wifi.tx.wont_be_nil
|
24
|
+
wifi.signal.wont_be_nil
|
25
|
+
wifi.tx_bitrate.wont_be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# To be used for handling long running processes
|
2
|
+
#
|
3
|
+
class OmfRc::DeferredProcess
|
4
|
+
include EM::Deferrable
|
5
|
+
|
6
|
+
# Pass a block of long running process
|
7
|
+
#
|
8
|
+
def fire(&block)
|
9
|
+
raise ArgumentError, "Missing code block to be executed" if block.nil?
|
10
|
+
|
11
|
+
EM.defer do
|
12
|
+
begin
|
13
|
+
result = block.call
|
14
|
+
succeed result
|
15
|
+
rescue => e
|
16
|
+
fail e
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Error during message processing, include message related information context_id and inform_to, for publishing errors to pubsub server
|
2
|
+
#
|
3
|
+
class OmfRc::MessageProcessError < StandardError
|
4
|
+
attr_reader :context_id, :inform_to
|
5
|
+
|
6
|
+
def initialize(context_id, inform_to, msg = nil)
|
7
|
+
@context_id = context_id
|
8
|
+
@inform_to = inform_to
|
9
|
+
super(msg)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'omf_common'
|
2
|
+
require 'securerandom'
|
3
|
+
require 'hashie'
|
4
|
+
require 'omf_rc/resource_proxy_dsl'
|
5
|
+
require 'omf_rc/resource_proxy/abstract_resource'
|
6
|
+
|
7
|
+
# Factory class for managing available proxies and creating new resource proxy instances
|
8
|
+
#
|
9
|
+
class OmfRc::ResourceFactory
|
10
|
+
# List of registered resource proxies
|
11
|
+
@@proxy_list = []
|
12
|
+
# List of registered utilities
|
13
|
+
@@utility_list = []
|
14
|
+
|
15
|
+
# By default, we use xmpp_blather dsl, which based on blather
|
16
|
+
DEFAULT_OPTS = {
|
17
|
+
dsl: 'xmpp_blather',
|
18
|
+
pubsub_host: 'pubsub'
|
19
|
+
}
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# Factory method to initiate new resource proxy
|
23
|
+
#
|
24
|
+
# @param (see OmfRc::ResourceProxy::AbstractResource#initialize)
|
25
|
+
#
|
26
|
+
# @see OmfRc::ResourceProxy::AbstractResource
|
27
|
+
def new(type, opts = nil, comm = nil, &block)
|
28
|
+
raise ArgumentError, "Resource type not found: #{type.to_s}" unless @@proxy_list.include?(type)
|
29
|
+
type = type.to_s
|
30
|
+
opts = opts ? DEFAULT_OPTS.merge(opts) : DEFAULT_OPTS
|
31
|
+
# Create a new instance of abstract resource
|
32
|
+
resource = OmfRc::ResourceProxy::AbstractResource.new(type, opts, comm)
|
33
|
+
# Then extend this instance with relevant module identified by type
|
34
|
+
resource.extend("OmfRc::ResourceProxy::#{type.camelcase}".constant)
|
35
|
+
# Execute resource before_ready hook if any
|
36
|
+
resource.before_ready if resource.respond_to? :before_ready
|
37
|
+
resource
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return the proxy list
|
41
|
+
def proxy_list
|
42
|
+
@@proxy_list
|
43
|
+
end
|
44
|
+
|
45
|
+
# Add a proxy to the list
|
46
|
+
def register_proxy(proxy)
|
47
|
+
@@proxy_list << proxy
|
48
|
+
end
|
49
|
+
|
50
|
+
# Return the utility list
|
51
|
+
def utility_list
|
52
|
+
@@utility_list
|
53
|
+
end
|
54
|
+
|
55
|
+
# Add a utility to the list
|
56
|
+
def register_utility(utility)
|
57
|
+
@@utility_list << utility
|
58
|
+
end
|
59
|
+
|
60
|
+
# Require files from default resource proxy library folder
|
61
|
+
#
|
62
|
+
def load_default_resource_proxies
|
63
|
+
Dir["#{File.dirname(__FILE__)}/resource_proxy/*.rb"].each do |file|
|
64
|
+
require "omf_rc/resource_proxy/#{File.basename(file).gsub(/\.rb/, '')}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def load_addtional_resource_proxies(folder)
|
69
|
+
Dir["#{folder}/*.rb"].each do |file|
|
70
|
+
require "#{folder}/#{File.basename(file).gsub(/\.rb/, '')}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|