omf_ec 6.1.1 → 6.1.2.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MGE2YjllOTM5NGZjYjA5OWU0MjVlMDdjMjRjOWVmOWMwMzk5MTE4NA==
5
- data.tar.gz: !binary |-
6
- N2YzNTFhNGQ2MDQzY2Q2MmM0YmYxN2ViNjdmZDEwMGY1Mjc2NGYxYQ==
2
+ SHA1:
3
+ metadata.gz: 945493d51a75ad28becc8a45ffb3622fc69ec31b
4
+ data.tar.gz: caf67781ab4f948f2f07c2b24e1019a2522219bb
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YmJkMGU2NDA5MTU5NjM3YjFkM2ZkNjJmYThjMmI3NzgwNDQyNzE0OWZhZTUy
10
- YWRhYjRhMjM4YzUzOTE0Zjc4ODBkMTBjODA0OTdkNDBmMzJlNWY2ZWY1ZDM0
11
- ZDI5YjgzYzA5NzVlY2U0YjM2YjA0NzcyZjQ4Y2JhYzZiNjJhMzY=
12
- data.tar.gz: !binary |-
13
- ZDRiOTYyYmJhMGJiMWQ4OTgwNjI5YWY5YTIwNjgzODI3ZDM2Mjc5ZjYwNTJi
14
- YzViMDk1NjEzYWFiYWU1YjkyZDA2NGJlODgyN2M0ZWE2YTVmM2FjMjUxMTUz
15
- OTRjZDBlNWI3ZWVhMjg2ZTkxNTVhNWI4YjMzZmM4MjQ1NDIzMTA=
6
+ metadata.gz: d7681fc0da5fdc1c90ba18420f2eb17ed45ff63651d7c288bf31f0b9cee304772a21168ad1a12e429813c83f1b49cea19585d9f537a4ab824439b2e8bad7f391
7
+ data.tar.gz: 63ec04e8ef79759874205ab753a3492321149353a5576952bae21639dedd3e5057cf29d16e40315dc69b32a2b2549593426e27103e9544932761ee4486b7e8b2
data/bin/omf_ec CHANGED
@@ -1,372 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Copyright (c) 2012 National ICT Australia Limited (NICTA).
4
- # This software may be used and distributed solely under the terms of the MIT license (License).
5
- # You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
6
- # By downloading or using this software you accept the terms and the liability disclaimer in the License.
7
-
8
- puts "OMF Experiment Controller - Copyright (c) 2012-13 National ICT Australia Limited (NICTA)"
9
- abort "Please use Ruby 1.9.3 or higher" if RUBY_VERSION < "1.9.3"
10
-
11
- require 'gli'
12
3
  require 'omf_ec'
4
+ require 'omf_ec/runner'
13
5
  $stdout.sync = true
14
6
 
15
- include GLI::App
16
- include OmfEc
17
-
18
- program_desc "Run a command on the testbed(s)"
19
- version OmfEc::VERSION
20
-
21
- desc "Debug mode (printing debug logging messages)"
22
- switch [:d, :debug]
23
-
24
- desc "URI for communication layer"
25
- arg_name "URI"
26
- default_value "xmpp://localhost"
27
- flag [:u, :uri]
28
-
29
- desc "Debug XMPP traffic mode (include XMPP debug logging messages under debug mode)."
30
- switch [:x, :xmpp]
31
-
32
- desc "Directory containing root certificates"
33
- arg_name "directory", :optional
34
- flag [:root_cert_dir]
35
-
36
- desc "Your certificate"
37
- arg_name "cert", :optional
38
- flag [:cert]
39
-
40
- desc "Your private key"
41
- arg_name "key", :optional
42
- flag [:key]
43
-
44
- desc "Log file directory"
45
- arg_name "directory"
46
- default_value "/tmp"
47
- flag [:log_file_dir]
48
-
49
- desc "Logging config file"
50
- arg_name "file"
51
- flag [:log_config]
52
-
53
- desc "Add some colours to logging"
54
- switch [:colour]
55
-
56
- desc "EC config file"
57
- arg_name "file"
58
- flag [:c, :config]
59
-
60
- $config_file = ".config/omf_ec.yml"
61
- ARGV.each_index {|a|
62
- if ARGV[a]=="-c" or ARGV[a]=="--config"
63
- $config_file = ARGV[a+1] if not ARGV[a+1].nil?
64
- end
65
- }
66
- # the path given here is relative to the user's home directory
67
- config_file($config_file)
68
-
69
- desc "Execute an experiment script"
70
- arg_name "path_to_script_file [-- --experiment_property value]"
71
- command :exec do |c|
72
- c.desc "Experiment name"
73
- c.arg_name "experiment_name"
74
- c.flag [:e, :experiment, "experiment-id"]
75
-
76
- c.desc "Slice name [Deprecated]"
77
- c.arg_name "slice_name"
78
- c.flag [:slice]
79
-
80
- c.desc "OML URI to use for collecting the experiment's measurements"
81
- c.arg_name "uri"
82
- c.flag [:oml_uri]
83
-
84
- c.desc "OML URI to use for EC Instrumentation"
85
- c.arg_name "uri"
86
- c.flag [:inst_oml_uri]
87
-
88
- c.desc "OML ID to use for EC Instrumentation"
89
- c.arg_name "id"
90
- c.flag [:inst_oml_id]
91
-
92
- c.desc "OML Domain to use for EC Instrumentation"
93
- c.arg_name "domain"
94
- c.flag [:inst_oml_domain]
95
-
96
- c.desc "Check script version (you need to define OMF_VERSIONS in your script"
97
- c.switch "version_check"
98
-
99
- c.desc "Parse graph definition to construct graph information in log output"
100
- c.switch [:g, "show-graph"]
101
-
102
- c.action do |global_options, options, args|
103
- help_now! "Missing experiment script" if args[0].nil?
104
- help_now! "Experiment script not found" unless File.exist?(File.expand_path(args[0]))
105
-
106
- # User-provided command line values for Experiment Properties cannot be
107
- # set here as the propertties have not been defined yet by the experiment.
108
- # Thus just pass them to the experiment, which will be responsible
109
- # for setting them later
110
- properties = {}
111
- if args.size > 1
112
- exp_properties = args[1..-1]
113
- exp_properties.in_groups_of(2) do |p|
114
- unless p[0] =~ /^--(.+)/ && !p[1].nil?
115
- help_now! "Malformatted properties '#{exp_properties.join(' ')}'"
116
- else
117
- properties[$1.to_sym] = p[1].ducktype
118
- end
119
- end
120
- OmfEc.experiment.cmdline_properties = properties
121
- end
122
-
123
- OmfEc.experiment.show_graph = options['show-graph']
124
-
125
- # FIXME this loading script is way too simple
126
- load_exp(File.expand_path(args[0]), global_options, options, properties)
127
- end
128
- end
129
-
130
- desc "Load an image onto the nodes"
131
- command :load do |c|
132
- #c.desc "use this testbed configuration in OMF 5 EC config file"
133
- #c.arg_name "AGGREGATE"
134
- #c.flag [:c, :config], :default_value => "default"
135
-
136
- c.desc "comma-separated list of nodes to image"
137
- c.arg_name "TOPOLOGY"
138
- c.flag [:t, :topology], :default_value => "system:topo:all"
139
-
140
- c.desc "disk image to load"
141
- c.arg_name "IMAGE"
142
- c.flag [:i, :image], :default_value => "baseline.ndz"
143
-
144
- c.desc "seconds to wait for the imaging process to complete"
145
- c.arg_name "TIMEOUT"
146
- c.flag [:o, :timeout], :default_value => "800"
147
-
148
- c.desc "resize the first partition to SIZE GB or to maximum size if SIZE=0 "+
149
- "or leave x percent of free space if SIZE=x%"
150
- c.arg_name "SIZE"
151
- c.flag [:r, :resize]
152
-
153
- c.desc "Path where the resulting Topologies should be saved"
154
- c.arg_name "PATH"
155
- c.flag [:outpath], :default_value => "/tmp"
156
-
157
- c.desc "Prefix to use for naming the resulting Topologies (default is your experiment ID)"
158
- c.arg_name "PREFIX"
159
- c.flag [:outprefix]
160
-
161
- c.action do |global_options, options, args|
162
- @cmd = "USER=#{ENV['USER']} omf-5.4 load -t #{options[:t]} -i #{options[:i]} "
163
- @cmd += "-o #{options[:o]} --outpath #{options[:outpath]} "
164
- @cmd += "-r #{options[:r]} " if options[:r]
165
- @cmd += "--outprefix #{options[:outprefix]} " if options[:outprefix]
166
- load_exp(@testbed_exp_path, global_options, options)
167
- end
168
- end
169
-
170
- desc "Save an image of a node"
171
- command :save do |c|
172
- #c.desc "use this testbed configuration in OMF 5 EC config file"
173
- #c.arg_name "AGGREGATE"
174
- #c.flag [:c, :config], :default_value => "default"
175
-
176
- c.desc "node to save from"
177
- c.arg_name "NODE"
178
- c.flag [:n, :node]
179
-
180
- c.desc "resize the first partition to SIZE GB or to maximum size if SIZE=0 "+
181
- "or leave x percent of free space if SIZE=x%"
182
- c.arg_name "SIZE"
183
- c.flag [:r, :resize]
184
-
185
- c.action do |global_options, options, args|
186
- @cmd = "USER=#{ENV['USER']} omf-5.4 save "
187
- @cmd += "-n #{options[:n]} " if options[:n]
188
- @cmd += "-r #{options[:r]} " if options[:r]
189
- load_exp(@testbed_exp_path, global_options, options)
190
- end
191
- end
192
-
193
- desc "Return the status of the nodes"
194
- command :stat do |c|
195
- c.desc "use this testbed configuration in OMF 5 EC config file"
196
- c.arg_name "AGGREGATE"
197
- c.flag [:C], :default_value => "default"
198
-
199
- c.desc "comma-separated list of nodes to image"
200
- c.arg_name "TOPOLOGY"
201
- c.flag [:t, :topology], :default_value => "system:topo:all"
202
-
203
- c.desc "print a summary of the node status for the testbed"
204
- c.switch [:s, :summary]
205
-
206
- c.action do |global_options, options, args|
207
- @cmd = "omf-5.4 stat -c #{options[:C]} -t #{options[:t]} "
208
- @cmd += "-s" if options[:s]
209
- load_exp(@testbed_exp_path, global_options, options)
210
- end
211
- end
212
-
213
- desc "Power on/off, reset or reboot the nodes"
214
- command :tell do |c|
215
- c.desc "use this testbed configuration in OMF 5 EC config file"
216
- c.arg_name "AGGREGATE"
217
- c.flag [:c, :config], :default_value => "default"
218
-
219
- c.desc "comma-separated list of nodes to image"
220
- c.arg_name "TOPOLOGY"
221
- c.flag [:t, :topology], :default_value => "system:topo:all"
222
-
223
- c.desc "
224
- 'on' turn node(s) ON -
225
- 'offs' turn node(s) OFF (soft) -
226
- 'offh' turn node(s) OFF (hard) -
227
- 'reboot' reboots node(s) (soft) -
228
- 'reset' resets node(s) (hard)"
229
- c.arg_name "ACTION"
230
- c.flag [:a, :action]
231
-
232
- c.action do |global_options, options, args|
233
- @cmd = "omf-5.4 tell -c #{options[:c]} -t #{options[:t]} "
234
- @cmd += "-a #{options[:a]} " if options[:a]
235
- load_exp(@testbed_exp_path, global_options, options)
236
- end
237
- end
238
-
239
- on_error do |exception|
240
- true
241
- end
242
-
243
- pre do |global_options, command, options, args|
244
- #opts = OmfCommon.load_yaml(config_file_name) if File.exist?(config_file_name)
245
- #opts.delete("commands")
246
- #global_options.merge!(opts)
247
-
248
- unless global_options[:uri]
249
- help_now! "Incomplete options. Need communication URI"
250
- end
251
-
252
- # Check version
253
- if options[:check]
254
- File.open(args[0], 'r') do |f|
255
- f.read.chomp.match(/OMF_VERSIONS\W*=\W*(.*)/)
256
- versions = $1
257
- unless versions && versions.split(',').include?(OmfCommon::PROTOCOL_VERSION)
258
- raise StandardError, "Could not find compatibile protocol version number in your script"
259
- end
260
- end
261
- end
262
-
263
- include OmfEc::DSL
264
-
265
- OmfEc.experiment.name = options[:experiment] if options[:experiment]
266
- OmfEc.experiment.oml_uri = options[:oml_uri] if options[:oml_uri]
267
-
268
- @testbed_exp_path = File.join(OmfEc.lib_root, "omf_ec/backward/exp/testbed.rb")
269
- end
270
-
271
- def setup_logging(global_options = {})
272
- if global_options[:xmpp]
273
- require 'blather'
274
- Blather.logger = logger
275
- end
276
-
277
- unless global_options[:debug]
278
- Logging.consolidate 'OmfCommon', 'OmfRc'
279
- end
280
-
281
- if global_options[:colour]
282
- Logging.logger.root.appenders.first.layout = Logging.layouts.pattern(date_pattern: '%F %T %z',
283
- color_scheme: 'default',
284
- pattern: '[%d] %-5l %c: %m\n')
285
- end
286
-
287
- # FIXME this should go to common setup
288
- if global_options[:log_file_dir] && File.exist?(File.expand_path(global_options[:log_file_dir]))
289
- Logging.logger.root.add_appenders(
290
- Logging.appenders.file(
291
- "#{File.expand_path(global_options[:log_file_dir])}/#{OmfEc.experiment.id}.log",
292
- :layout => Logging.layouts.pattern(:date_pattern => '%F %T %z',
293
- :pattern => '[%d] %-5l %c: %m\n')))
294
- end
295
-
296
- if OmfEc.experiment.oml_uri
297
- require 'oml4r/logging/oml4r_appender'
298
- Logging.logger.root.add_appenders(Logging.appenders.oml4r('oml4r', :appName => 'omf_ec', :domain => "#{OmfEc.experiment.id}", :collect => "#{OmfEc.experiment.oml_uri}"))
299
- end
300
-
301
- OmfCommon.load_logging_config(global_options[:log_config])
302
- end
303
-
304
- def load_exp(exp_path, global_options = {} , options = {}, properties = {})
305
- begin
306
- if options[:inst_oml_uri] && options[:inst_oml_id] && options[:inst_oml_domain]
307
- require 'oml4r'
308
- instrument_ec = OML4R::init(nil, { collect: options[:inst_oml_uri], nodeID: options[:inst_oml_id], domain: options[:inst_oml_domain] , appName: File.basename($PROGRAM_NAME)} )
309
- OmfCommon::Measure.enable if instrument_ec
310
- end
311
-
312
- opts = {
313
- communication: { url: global_options[:uri] },
314
- eventloop: { type: :em },
315
- logging: {
316
- level: { default: global_options[:debug] ? 'debug' : 'info' },
317
- appenders: {
318
- stdout: {
319
- date_pattern: '%H:%M:%S',
320
- pattern: '%d %-5l %c{2}: %m\n'
321
- }
322
- }
323
- }
324
- }
325
-
326
- opts[:communication][:auth] = { authenticate: true } if global_options[:cert]
327
-
328
- OmfCommon.init(:development, opts) do |el|
329
-
330
- setup_logging(global_options)
331
-
332
- OmfCommon.comm.on_connected do |comm|
333
- info "OMF Experiment Controller #{OmfEc::VERSION} - Start"
334
- info "Connected using #{comm.conn_info}"
335
- info "Execute: #{exp_path}"
336
- info "Properties: #{OmfEc.experiment.cmdline_properties}"
337
-
338
- if opts[:communication][:auth] && opts[:communication][:auth][:authenticate]
339
- ec_cert = OmfCommon.load_credentials(
340
- root_cert_dir: global_options[:root_cert_dir],
341
- entity_cert: global_options[:cert],
342
- entity_key: global_options[:key]
343
- )
344
-
345
- ec_cert.resource_id = OmfCommon.comm.local_address
346
- OmfCommon::Auth::CertificateStore.instance.register(ec_cert)
347
- end
348
-
349
- OmfEc.experiment.log_metadata("ec_version", "#{OmfEc::VERSION}")
350
- OmfEc.experiment.log_metadata("exp_path", exp_path)
351
- OmfEc.experiment.log_metadata("ec_pid", "#{Process.pid}")
352
-
353
- begin
354
- include OmfEc::Backward::DefaultEvents
355
- load exp_path
356
- OmfEc::Experiment.start
357
- rescue => e
358
- OmfEc.experiment.log_metadata("state", "error")
359
- error e.message
360
- error e.backtrace.join("\n")
361
- end
362
-
363
- comm.on_interrupted { OmfEc::Experiment.done }
364
- end
365
- end
366
- rescue => e
367
- logger.fatal e.message
368
- logger.fatal e.backtrace.join("\n")
369
- end
370
- end
371
-
372
- exit run(ARGV)
7
+ OmfEc::Runner.new.run
@@ -6,11 +6,9 @@
6
6
  module OmfEc
7
7
  module Backward
8
8
  module DefaultEvents
9
-
10
9
  class << self
11
10
  def included(base)
12
- base.instance_eval do
13
-
11
+ base.class_eval do
14
12
  def all_nodes_up?(state)
15
13
  all_groups? do |g|
16
14
  plan = g.members.values.uniq.sort
@@ -36,11 +34,13 @@ module OmfEc
36
34
  end
37
35
 
38
36
  def all_apps_ready?(state)
37
+ results = []
39
38
  all_groups? do |g|
40
39
  plan = g.app_contexts.size * g.members.values.uniq.size
41
- actual = state.count { |v| v.joined?(g.address("application")) }
42
- plan == 0 ? false : plan == actual
40
+ actual = state.count { |v| v.joined?(g.address("application")) }
41
+ results << (plan == actual) unless (plan == 0)
43
42
  end
43
+ !results.include?(false)
44
44
  end
45
45
 
46
46
  def all_nodes_up_cbk
@@ -93,13 +93,12 @@ module OmfEc
93
93
 
94
94
  def_event :ALL_APPS_DONE do |state|
95
95
  all_nodes_up?(state) &&
96
- all_groups? do |g|
97
- plan = (g.execs.size + g.app_contexts.size) * g.members.values.uniq.size
98
- actual = state.count { |v| v.joined?(g.address("application")) && v[:event] == 'EXIT' }
99
- plan == 0 ? false : plan == actual
100
- end
96
+ all_groups? do |g|
97
+ plan = (g.execs.size + g.app_contexts.size) * g.members.values.uniq.size
98
+ actual = state.count { |v| v.joined?(g.address("application")) && v[:event] == 'EXIT' }
99
+ plan == 0 ? false : plan == actual
100
+ end
101
101
  end
102
-
103
102
  end
104
103
  end
105
104
  end
@@ -16,6 +16,8 @@ module OmfEc
16
16
  v5_style(:allGroups, base)
17
17
  v5_style(:allNodes!, base)
18
18
  v5_style(:defGraph, base)
19
+ v5_style(:loadOEDL, base)
20
+ v5_style(:ensureProperty, base)
19
21
  end
20
22
 
21
23
  def v5_style(name, base)
@@ -52,6 +54,7 @@ module OmfEc
52
54
  warn "Calling 'wait' or 'sleep' will block entire EC event loop. Please try 'after' or 'every'"
53
55
  sleep duration.to_s.to_i
54
56
  end
57
+
55
58
  end
56
59
  end
57
60
  end
@@ -16,14 +16,15 @@ module OmfEc
16
16
 
17
17
  # Create an application for the group and start it
18
18
  #
19
- def exec(name)
19
+ def exec(command)
20
+ name = SecureRandom.uuid
21
+
20
22
  self.synchronize do
21
23
  self.execs << name
22
24
  end
23
- create_resource(name, type: 'application', binary_path: name)
25
+ create_resource(name, type: 'application', binary_path: command)
24
26
 
25
- e_uid = SecureRandom.uuid
26
- e_name = "#{self.name}_application_#{name}_created_#{e_uid}"
27
+ e_name = "#{self.name}_application_#{name}_created"
27
28
 
28
29
  resource_group_name = self.address("application")
29
30
 
@@ -68,8 +69,8 @@ module OmfEc
68
69
  end
69
70
  end
70
71
 
71
- def addApplication(name, &block)
72
- app_cxt = OmfEc::Context::AppContext.new(name,self)
72
+ def addApplication(name, location = nil, &block)
73
+ app_cxt = OmfEc::Context::AppContext.new(name,location,self)
73
74
  block.call(app_cxt) if block
74
75
  self.app_contexts << app_cxt
75
76
  end
@@ -0,0 +1,28 @@
1
+ # Copyright (c) 2012 National ICT Australia Limited (NICTA).
2
+ # This software may be used and distributed solely under the terms of the MIT license (License).
3
+ # You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
4
+ # By downloading or using this software you accept the terms and the liability disclaimer in the License.
5
+
6
+ # This OEDL script implements a timeout timer for resources to checked-in an
7
+ # experiment. When it is loaded as part as another experiment, it will wait
8
+ # for the specified time in the experiment property 'oedl_timeout'. When that
9
+ # wait is over, it checks if all resources defined in the experiment have
10
+ # joined all their groups (also as defined in the experiment). If not, then
11
+ # it stops the experiment.
12
+ #
13
+ # The default timeout value is set here to 120 s. To modify that you should
14
+ # set in your experiment the oedl_timeout property to the desired timeout in
15
+ # second. You must do that prior to or as you load this script.
16
+ #
17
+ # For example, in your OEDL experiment:
18
+ #
19
+ # load_oedl('omf_ec/backward/timeout_resources', { oedl_timeout: 180 })
20
+ #
21
+ ensureProperty('oedl_timeout',120,'default timeout in second')
22
+ info "Waiting for all resources to join... (timeout set to #{property.oedl_timeout} s)"
23
+ after property.oedl_timeout.to_i do
24
+ unless all_nodes_up?(OmfEc.experiment.state)
25
+ info "Waited #{property.oedl_timeout} s for all resources to join, but still some missing! Aborting the experiment execution now!"
26
+ Experiment.done
27
+ end
28
+ end
@@ -14,7 +14,8 @@ module OmfEc::Context
14
14
  # values for each. Thus we need to distinguish these different context
15
15
  @@context_count = Hash.new
16
16
 
17
- def initialize(name, group)
17
+ def initialize(name, location = nil, group)
18
+ load_oedl(location) unless location.nil?
18
19
  if OmfEc.experiment.app_definitions.key?(name)
19
20
  self.app_def = OmfEc.experiment.app_definitions[name]
20
21
  self.param_values = Hash.new
data/lib/omf_ec/dsl.rb CHANGED
@@ -3,6 +3,8 @@
3
3
  # You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
4
4
  # By downloading or using this software you accept the terms and the liability disclaimer in the License.
5
5
 
6
+ require 'active_support'
7
+ require 'active_support/deprecation'
6
8
  require 'active_support/core_ext'
7
9
  require 'eventmachine'
8
10
 
@@ -63,7 +65,7 @@ module OmfEc
63
65
  OmfCommon.eventloop.every(time, &block)
64
66
  end
65
67
 
66
- def def_application(name,&block)
68
+ def def_application(name, &block)
67
69
  app_def = OmfEc::AppDefinition.new(name)
68
70
  OmfEc.experiment.app_definitions[name] = app_def
69
71
  block.call(app_def) if block
@@ -135,6 +137,17 @@ module OmfEc
135
137
  return OmfEc.experiment.property
136
138
  end
137
139
 
140
+ # Check if a property exist, if not then define it
141
+ # Take the same parameter as def_property
142
+ #
143
+ def ensure_property(name, default_value, description = nil, type = nil)
144
+ begin
145
+ property[name]
146
+ rescue
147
+ def_property(name, default_value, description, type)
148
+ end
149
+ end
150
+
138
151
  alias_method :prop, :property
139
152
 
140
153
  # Check if all elements in array equal the value provided
@@ -198,6 +211,43 @@ module OmfEc
198
211
  end
199
212
  end
200
213
 
201
- include OmfEc::Backward::DSL
214
+ # Load an additional OEDL script
215
+ #
216
+ # First try to load the script from the paths associated to this running
217
+ # Ruby instance. This would allow the loading of scripts shipped with
218
+ # the EC gem. If that fails, then look for the script in the local file
219
+ # system or at the given web URL.
220
+ #
221
+ # If an optional has of key/value is provided, then define an OMF
222
+ # Experiment Property for each keys and assigne them the values.
223
+ #
224
+ # @param location name, path or URL for the OEDL script to load
225
+ # @param opts optional hash of key/values for extra Experiment Property to define
226
+ #
227
+ def load_oedl(location, opts = {})
228
+ # Define the additional properties from opts
229
+ opts.each { |k,v| def_property(k, v,) }
230
+ # Try to load OEDL Library as built-in then external
231
+ begin
232
+ require location
233
+ info "Loaded built-in OEDL library '#{location}'"
234
+ rescue LoadError
235
+ begin
236
+ require 'open-uri'
237
+ require 'tempfile'
238
+ file = Tempfile.new("oedl-#{Time.now.to_i}")
239
+ open(location) { |io| file.write(io.read) }
240
+ file.close
241
+ load(file.path)
242
+ file.unlink
243
+ info "Loaded external OEDL library '#{location}'"
244
+ rescue Exception => e
245
+ error "Fail loading external OEDL library '#{location}': #{e}"
246
+ end
247
+ rescue Exception => e
248
+ error "Fail loading built-in OEDL library '#{location}': #{e}"
249
+ end
250
+ end
251
+
202
252
  end
203
253
  end
@@ -145,7 +145,8 @@ module OmfEc
145
145
 
146
146
  def add_event(name, trigger)
147
147
  self.synchronize do
148
- raise RuntimeError, "Event '#{name}' has already been defined" if event(name)
148
+ warn "Event '#{name}' has already been defined. Overwriting it now." if event(name)
149
+ @events.delete_if { |e| e[:name] == name }
149
150
  @events << { name: name, trigger: trigger, aliases: [] }
150
151
  end
151
152
  end
@@ -0,0 +1,266 @@
1
+ # Copyright (c) 2014 National ICT Australia Limited (NICTA).
2
+ # This software may be used and distributed solely under the terms of the MIT license (License).
3
+ # You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
4
+ # By downloading or using this software you accept the terms and the liability disclaimer in the License
5
+
6
+ require 'hashie'
7
+
8
+ module OmfEc
9
+ class Runner
10
+ include Hashie
11
+
12
+ def initialize
13
+ @gem_version = OmfEc::VERSION
14
+ @oml_enabled = false
15
+ @executable_name = File.basename($PROGRAM_NAME)
16
+
17
+ @oml_opts = {
18
+ appName: @executable_name,
19
+ afterParse: lambda { |o| parse_cmd_opts }
20
+ }
21
+
22
+ # Default configuration options
23
+ @config_opts = Mash.new(
24
+ environment: 'development',
25
+ communication: { url: "amqp://localhost" },
26
+ )
27
+
28
+ @cmd_opts = Mash.new
29
+
30
+ @argv = ARGV.dup
31
+ end
32
+
33
+ def oml_init
34
+ begin
35
+ @oml_enabled = OML4R::init(ARGV, @oml_opts) do |op|
36
+ op.banner = "OMF Experiment Controller version '#{@gem_version}'\n"
37
+ op.banner += "Usage: #{@executable_name} [options] path_to_oedl_file [-- --experiment_property value]"
38
+
39
+ op.on("-u", "--uri ADDRESS", "URI for communication layer [amqp://localhost]") do |uri|
40
+ @cmd_opts[:uri] = uri
41
+ remove_cmd_opts_from_argv("-u", "--uri", uri)
42
+ end
43
+
44
+ op.on("-c CONFIGFILE", "Configuration File") do |file|
45
+ @cmd_opts[:config_file] = file
46
+ remove_cmd_opts_from_argv("-c", file)
47
+ end
48
+
49
+ op.on("--log_config CONFIGFILE", "Logging Configuration File") do |file|
50
+ @cmd_opts[:logging_configfile] = file
51
+ remove_cmd_opts_from_argv("--log_config", file)
52
+ end
53
+
54
+ op.on("-e ENVIRONMENT", "Environment (development, production ...) [#{@config_opts[:environment]}]") do |e|
55
+ @cmd_opts[:environment] = e
56
+ remove_cmd_opts_from_argv("-e", e)
57
+ end
58
+
59
+ op.on("--root_cert_dir DIRECTORY", "Directory containing root certificates") do |dir|
60
+ @cmd_opts[:root_cert_dir] = dir
61
+ remove_cmd_opts_from_argv("--root_cert_dir", dir)
62
+ end
63
+
64
+ op.on("--cert CERTIFICATE", "Your certificate") do |cert|
65
+ @cmd_opts[:cert] = cert
66
+ remove_cmd_opts_from_argv("--cert", cert)
67
+ end
68
+
69
+ op.on("--key KEY", "Your private key") do |key|
70
+ @cmd_opts[:key] = key
71
+ remove_cmd_opts_from_argv("--key", key)
72
+ end
73
+
74
+ op.on("--name", "--experiment EXPERIMENT_NAME", "Experiment name") do |e_name|
75
+ @cmd_opts[:experiment_name] = e_name
76
+ remove_cmd_opts_from_argv("--name", "--experiment", e_name)
77
+ end
78
+
79
+ op.on("--slice SLICE_NAME", "Slice name [Deprecated]") do |slice|
80
+ @cmd_opts[:slice] = slice
81
+ remove_cmd_opts_from_argv("--slice", slice)
82
+ end
83
+
84
+ op.on("--inst_oml_uri URI", "EC Instrumentation: OML URI to use") do |uri|
85
+ @cmd_opts[:inst_oml_uri] = uri
86
+ remove_cmd_opts_from_argv("--inst_oml_uri", uri)
87
+ end
88
+
89
+ op.on("--inst_oml_id ID", "EC Instrumentation: OML ID to use") do |id|
90
+ @cmd_opts[:inst_oml_id] = id
91
+ remove_cmd_opts_from_argv("--inst_oml_id", id)
92
+ end
93
+
94
+ op.on("--inst_oml_domain DOMAIN", "EC Instrumentation: OML Domain to use") do |domain|
95
+ @cmd_opts[:inst_oml_domain] = domain
96
+ remove_cmd_opts_from_argv("--inst_oml_domain", domain)
97
+ end
98
+
99
+ op.on("-g", "--show-graph", "Parse graph definition to construct graph information in log output") do
100
+ @cmd_opts['show-graph'] = true
101
+ remove_cmd_opts_from_argv("--show-graph")
102
+ end
103
+
104
+ op.on("-v", "--version", "Show version") do
105
+ puts "OMF Experiment Controller version '#{@gem_version}'"
106
+ exit
107
+ end
108
+
109
+ op.on("-d", "--debug", "Debug mode (printing debug logging messages)") do
110
+ @cmd_opts[:debug] = true
111
+ remove_cmd_opts_from_argv("-d", "--debug")
112
+ end
113
+
114
+ op.on("-h", "--help", "Show this message") do
115
+ puts op
116
+ exit
117
+ end
118
+ end
119
+ rescue OML4R::MissingArgumentException => e
120
+ puts "Warning: #{e.message} to instrument, so it will run without instrumentation. (see --oml-help)"
121
+ rescue => e
122
+ puts e.message
123
+ puts e.backtrace.join("\n")
124
+ exit(1)
125
+ end
126
+ end
127
+
128
+ def parse_cmd_opts
129
+ parse_config_file
130
+
131
+ # uri in command line is short for communication/url
132
+ uri = @cmd_opts.delete(:uri)
133
+ @config_opts[:communication][:url] = uri if uri
134
+ @config_opts[:communication][:auth] = { authenticate: true } if @cmd_opts[:cert]
135
+ @config_opts.merge!(@cmd_opts)
136
+ end
137
+
138
+ def parse_config_file
139
+ if (config_file = @cmd_opts.delete(:config_file))
140
+ if File.exist?(config_file)
141
+ @config_opts.merge!(OmfCommon.load_yaml(config_file))
142
+ else
143
+ puts "Config file '#{config_file}' doesn't exist"
144
+ exit(1)
145
+ end
146
+ end
147
+ end
148
+
149
+ def remove_cmd_opts_from_argv(*args)
150
+ args.each { |v| @argv.delete(v) }
151
+ end
152
+
153
+ def setup_experiment
154
+ OmfEc.experiment.name = @config_opts[:experiment_name] if @config_opts[:experiment_name]
155
+ OmfEc.experiment.oml_uri = @config_opts[:oml_uri] if @config_opts[:oml_uri]
156
+ OmfEc.experiment.show_graph = @config_opts['show-graph']
157
+
158
+ # Instrument EC
159
+ if @config_opts[:inst_oml_uri] && @config_opts[:inst_oml_id] && @config_opts[:inst_oml_domain]
160
+ instrument_ec = OML4R::init(nil, {
161
+ collect: @config_opts[:inst_oml_uri],
162
+ nodeID: @config_opts[:inst_oml_id],
163
+ domain: @config_opts[:inst_oml_domain],
164
+ appName: @executable_name
165
+ })
166
+
167
+ OmfCommon::Measure.enable if instrument_ec
168
+ end
169
+
170
+ remove_cmd_opts_from_argv("exec")
171
+
172
+ @oedl_path = @argv[0] && File.expand_path(@argv[0])
173
+
174
+ if @oedl_path.nil? || !File.exist?(@oedl_path)
175
+ puts "Experiment script '#{@argv[0]}' not found"
176
+ exit(1)
177
+ end
178
+
179
+ # User-provided command line values for Experiment Properties cannot be
180
+ # set here as the properties have not been defined yet by the experiment.
181
+ # Thus just pass them to the experiment, which will be responsible
182
+ # for setting them later
183
+ properties = {}
184
+ if @argv.size > 1 && @argv[1] == "--"
185
+ exp_properties = @argv[2..-1]
186
+ exp_properties.in_groups_of(2) do |p|
187
+ unless p[0] =~ /^--(.+)/ && !p[1].nil?
188
+ puts "Malformatted properties '#{exp_properties.join(' ')}'"
189
+ exit(1)
190
+ else
191
+ properties[$1.to_sym] = p[1].ducktype
192
+ end
193
+ end
194
+ OmfEc.experiment.cmdline_properties = properties
195
+ end
196
+ end
197
+
198
+ def setup_logging
199
+ OmfCommon.load_logging_config(@config_opts[:logging_configfile])
200
+
201
+ if @config_opts[:debug]
202
+ Logging.logger.root.level = 'debug'
203
+ else
204
+ Logging.consolidate 'OmfCommon', 'OmfRc'
205
+ end
206
+
207
+ if OmfEc.experiment.oml_uri
208
+ require 'oml4r/logging/oml4r_appender'
209
+ Logging.logger.root.add_appenders(Logging.appenders.oml4r('oml4r', :appName => 'omf_ec', :domain => "#{OmfEc.experiment.id}", :collect => "#{OmfEc.experiment.oml_uri}"))
210
+ end
211
+ end
212
+
213
+ def load_experiment
214
+ begin
215
+ OmfCommon.init(@config_opts.delete(:environment), @config_opts) do |el|
216
+ setup_logging
217
+ OmfCommon.comm.on_connected do |comm|
218
+ info "OMF Experiment Controller #{OmfEc::VERSION} - Start"
219
+ info "Connected using #{comm.conn_info}"
220
+ info "Execute: #{@oedl_path}"
221
+ info "Properties: #{OmfEc.experiment.cmdline_properties}"
222
+
223
+ if @config_opts[:communication][:auth] && @config_opts[:communication][:auth][:authenticate]
224
+ ec_cert = OmfCommon.load_credentials(
225
+ root_cert_dir: @config_opts[:root_cert_dir],
226
+ entity_cert: @config_opts[:cert],
227
+ entity_key: @config_opts[:key]
228
+ )
229
+
230
+ ec_cert.resource_id = OmfCommon.comm.local_address
231
+ OmfCommon::Auth::CertificateStore.instance.register(ec_cert)
232
+ end
233
+
234
+ OmfEc.experiment.log_metadata("ec_version", "#{OmfEc::VERSION}")
235
+ OmfEc.experiment.log_metadata("exp_path", @oedl_path)
236
+ OmfEc.experiment.log_metadata("ec_pid", "#{Process.pid}")
237
+
238
+ begin
239
+ load @oedl_path
240
+ OmfEc::Experiment.start
241
+ rescue => e
242
+ OmfEc.experiment.log_metadata("state", "error")
243
+ error e.message
244
+ error e.backtrace.join("\n")
245
+ end
246
+
247
+ trap(:TERM) { OmfEc::Experiment.done }
248
+ trap(:INT) { OmfEc::Experiment.done }
249
+ end
250
+ end
251
+ rescue => e
252
+ logger.fatal e.message
253
+ logger.fatal e.backtrace.join("\n")
254
+ puts "Experiment controller exits unexpectedly"
255
+ puts e
256
+ exit(1)
257
+ end
258
+ end
259
+
260
+ def run
261
+ oml_init
262
+ setup_experiment
263
+ load_experiment
264
+ end
265
+ end
266
+ end
data/lib/omf_ec.rb CHANGED
@@ -21,14 +21,14 @@ require "omf_ec/dsl"
21
21
 
22
22
  module OmfEc
23
23
 
24
- # OML Measurement Point (MP)
25
- # This MP is for measurements about messages received by the Resource Proxy
26
- class OmfEc::MPReceived < OML4R::MPBase
27
- name :ec_received
28
- param :time, :type => :double # Time (s) when this message was received
29
- param :topic, :type => :string # Pubsub topic where this message came from
30
- param :mid, :type => :string # Unique ID this message
31
- end
24
+ # OML Measurement Point (MP)
25
+ # This MP is for measurements about messages received by the Resource Proxy
26
+ class OmfEc::MPReceived < OML4R::MPBase
27
+ name :ec_received
28
+ param :time, :type => :double # Time (s) when this message was received
29
+ param :topic, :type => :string # Pubsub topic where this message came from
30
+ param :mid, :type => :string # Unique ID this message
31
+ end
32
32
 
33
33
  class << self
34
34
  # Experiment instance
@@ -101,3 +101,9 @@ end
101
101
  end
102
102
  end
103
103
  end
104
+
105
+ include OmfEc::DSL
106
+ include OmfEc::Backward::DSL
107
+ include OmfEc::Backward::DefaultEvents
108
+
109
+ Experiment = OmfEc::Experiment
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omf_ec
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.1
4
+ version: 6.1.2.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - NICTA
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-31 00:00:00.000000000 Z
11
+ date: 2014-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -42,42 +42,42 @@ dependencies:
42
42
  name: simplecov
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: pry
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: mocha
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ! '>='
73
+ - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ! '>='
80
+ - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
@@ -86,40 +86,40 @@ dependencies:
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 6.1.1
89
+ version: 6.1.2.pre
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 6.1.1
96
+ version: 6.1.2.pre
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: gli
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ! '>='
101
+ - - '>='
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ! '>='
108
+ - - '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: sequel
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ! '>='
115
+ - - '>='
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ! '>='
122
+ - - '>='
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  description: Experiment controller of OMF, a generic framework for controlling and
@@ -151,6 +151,7 @@ files:
151
151
  - lib/omf_ec/backward/dsl.rb
152
152
  - lib/omf_ec/backward/exp/testbed.rb
153
153
  - lib/omf_ec/backward/group.rb
154
+ - lib/omf_ec/backward/timeout_resources.rb
154
155
  - lib/omf_ec/context.rb
155
156
  - lib/omf_ec/context/app_context.rb
156
157
  - lib/omf_ec/context/def_app_context.rb
@@ -163,6 +164,7 @@ files:
163
164
  - lib/omf_ec/graph.rb
164
165
  - lib/omf_ec/graph/graph_description.rb
165
166
  - lib/omf_ec/group.rb
167
+ - lib/omf_ec/runner.rb
166
168
  - lib/omf_ec/version.rb
167
169
  - omf_ec.gemspec
168
170
  - test/omf_ec/app_context_spec.rb
@@ -182,18 +184,25 @@ require_paths:
182
184
  - lib
183
185
  required_ruby_version: !ruby/object:Gem::Requirement
184
186
  requirements:
185
- - - ! '>='
187
+ - - '>='
186
188
  - !ruby/object:Gem::Version
187
189
  version: 1.9.3
188
190
  required_rubygems_version: !ruby/object:Gem::Requirement
189
191
  requirements:
190
- - - ! '>='
192
+ - - '>'
191
193
  - !ruby/object:Gem::Version
192
- version: '0'
194
+ version: 1.3.1
193
195
  requirements: []
194
196
  rubyforge_project: omf_ec
195
- rubygems_version: 2.2.2
197
+ rubygems_version: 2.1.11
196
198
  signing_key:
197
199
  specification_version: 4
198
200
  summary: OMF experiment controller
199
- test_files: []
201
+ test_files:
202
+ - test/omf_ec/app_context_spec.rb
203
+ - test/omf_ec/context_spec.rb
204
+ - test/omf_ec/dsl_spec.rb
205
+ - test/omf_ec/experiment_property_spec.rb
206
+ - test/omf_ec/experiment_spec.rb
207
+ - test/omf_ec/group_spec.rb
208
+ - test/test_helper.rb