omf_ec 6.1.1 → 6.1.2.pre

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.
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