bin/omf_ec in omf_ec-6.1.1 vs bin/omf_ec in omf_ec-6.1.2.pre

- old
+ new

@@ -1,372 +1,7 @@ #!/usr/bin/env ruby -# Copyright (c) 2012 National ICT Australia Limited (NICTA). -# This software may be used and distributed solely under the terms of the MIT license (License). -# You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT. -# By downloading or using this software you accept the terms and the liability disclaimer in the License. - -puts "OMF Experiment Controller - Copyright (c) 2012-13 National ICT Australia Limited (NICTA)" -abort "Please use Ruby 1.9.3 or higher" if RUBY_VERSION < "1.9.3" - -require 'gli' require 'omf_ec' +require 'omf_ec/runner' $stdout.sync = true -include GLI::App -include OmfEc - -program_desc "Run a command on the testbed(s)" -version OmfEc::VERSION - -desc "Debug mode (printing debug logging messages)" -switch [:d, :debug] - -desc "URI for communication layer" -arg_name "URI" -default_value "xmpp://localhost" -flag [:u, :uri] - -desc "Debug XMPP traffic mode (include XMPP debug logging messages under debug mode)." -switch [:x, :xmpp] - -desc "Directory containing root certificates" -arg_name "directory", :optional -flag [:root_cert_dir] - -desc "Your certificate" -arg_name "cert", :optional -flag [:cert] - -desc "Your private key" -arg_name "key", :optional -flag [:key] - -desc "Log file directory" -arg_name "directory" -default_value "/tmp" -flag [:log_file_dir] - -desc "Logging config file" -arg_name "file" -flag [:log_config] - -desc "Add some colours to logging" -switch [:colour] - -desc "EC config file" -arg_name "file" -flag [:c, :config] - -$config_file = ".config/omf_ec.yml" -ARGV.each_index {|a| - if ARGV[a]=="-c" or ARGV[a]=="--config" - $config_file = ARGV[a+1] if not ARGV[a+1].nil? - end -} -# the path given here is relative to the user's home directory -config_file($config_file) - -desc "Execute an experiment script" -arg_name "path_to_script_file [-- --experiment_property value]" -command :exec do |c| - c.desc "Experiment name" - c.arg_name "experiment_name" - c.flag [:e, :experiment, "experiment-id"] - - c.desc "Slice name [Deprecated]" - c.arg_name "slice_name" - c.flag [:slice] - - c.desc "OML URI to use for collecting the experiment's measurements" - c.arg_name "uri" - c.flag [:oml_uri] - - c.desc "OML URI to use for EC Instrumentation" - c.arg_name "uri" - c.flag [:inst_oml_uri] - - c.desc "OML ID to use for EC Instrumentation" - c.arg_name "id" - c.flag [:inst_oml_id] - - c.desc "OML Domain to use for EC Instrumentation" - c.arg_name "domain" - c.flag [:inst_oml_domain] - - c.desc "Check script version (you need to define OMF_VERSIONS in your script" - c.switch "version_check" - - c.desc "Parse graph definition to construct graph information in log output" - c.switch [:g, "show-graph"] - - c.action do |global_options, options, args| - help_now! "Missing experiment script" if args[0].nil? - help_now! "Experiment script not found" unless File.exist?(File.expand_path(args[0])) - - # User-provided command line values for Experiment Properties cannot be - # set here as the propertties have not been defined yet by the experiment. - # Thus just pass them to the experiment, which will be responsible - # for setting them later - properties = {} - if args.size > 1 - exp_properties = args[1..-1] - exp_properties.in_groups_of(2) do |p| - unless p[0] =~ /^--(.+)/ && !p[1].nil? - help_now! "Malformatted properties '#{exp_properties.join(' ')}'" - else - properties[$1.to_sym] = p[1].ducktype - end - end - OmfEc.experiment.cmdline_properties = properties - end - - OmfEc.experiment.show_graph = options['show-graph'] - - # FIXME this loading script is way too simple - load_exp(File.expand_path(args[0]), global_options, options, properties) - end -end - -desc "Load an image onto the nodes" -command :load do |c| - #c.desc "use this testbed configuration in OMF 5 EC config file" - #c.arg_name "AGGREGATE" - #c.flag [:c, :config], :default_value => "default" - - c.desc "comma-separated list of nodes to image" - c.arg_name "TOPOLOGY" - c.flag [:t, :topology], :default_value => "system:topo:all" - - c.desc "disk image to load" - c.arg_name "IMAGE" - c.flag [:i, :image], :default_value => "baseline.ndz" - - c.desc "seconds to wait for the imaging process to complete" - c.arg_name "TIMEOUT" - c.flag [:o, :timeout], :default_value => "800" - - c.desc "resize the first partition to SIZE GB or to maximum size if SIZE=0 "+ - "or leave x percent of free space if SIZE=x%" - c.arg_name "SIZE" - c.flag [:r, :resize] - - c.desc "Path where the resulting Topologies should be saved" - c.arg_name "PATH" - c.flag [:outpath], :default_value => "/tmp" - - c.desc "Prefix to use for naming the resulting Topologies (default is your experiment ID)" - c.arg_name "PREFIX" - c.flag [:outprefix] - - c.action do |global_options, options, args| - @cmd = "USER=#{ENV['USER']} omf-5.4 load -t #{options[:t]} -i #{options[:i]} " - @cmd += "-o #{options[:o]} --outpath #{options[:outpath]} " - @cmd += "-r #{options[:r]} " if options[:r] - @cmd += "--outprefix #{options[:outprefix]} " if options[:outprefix] - load_exp(@testbed_exp_path, global_options, options) - end -end - -desc "Save an image of a node" -command :save do |c| - #c.desc "use this testbed configuration in OMF 5 EC config file" - #c.arg_name "AGGREGATE" - #c.flag [:c, :config], :default_value => "default" - - c.desc "node to save from" - c.arg_name "NODE" - c.flag [:n, :node] - - c.desc "resize the first partition to SIZE GB or to maximum size if SIZE=0 "+ - "or leave x percent of free space if SIZE=x%" - c.arg_name "SIZE" - c.flag [:r, :resize] - - c.action do |global_options, options, args| - @cmd = "USER=#{ENV['USER']} omf-5.4 save " - @cmd += "-n #{options[:n]} " if options[:n] - @cmd += "-r #{options[:r]} " if options[:r] - load_exp(@testbed_exp_path, global_options, options) - end -end - -desc "Return the status of the nodes" -command :stat do |c| - c.desc "use this testbed configuration in OMF 5 EC config file" - c.arg_name "AGGREGATE" - c.flag [:C], :default_value => "default" - - c.desc "comma-separated list of nodes to image" - c.arg_name "TOPOLOGY" - c.flag [:t, :topology], :default_value => "system:topo:all" - - c.desc "print a summary of the node status for the testbed" - c.switch [:s, :summary] - - c.action do |global_options, options, args| - @cmd = "omf-5.4 stat -c #{options[:C]} -t #{options[:t]} " - @cmd += "-s" if options[:s] - load_exp(@testbed_exp_path, global_options, options) - end -end - -desc "Power on/off, reset or reboot the nodes" -command :tell do |c| - c.desc "use this testbed configuration in OMF 5 EC config file" - c.arg_name "AGGREGATE" - c.flag [:c, :config], :default_value => "default" - - c.desc "comma-separated list of nodes to image" - c.arg_name "TOPOLOGY" - c.flag [:t, :topology], :default_value => "system:topo:all" - - c.desc " - 'on' turn node(s) ON - - 'offs' turn node(s) OFF (soft) - - 'offh' turn node(s) OFF (hard) - - 'reboot' reboots node(s) (soft) - - 'reset' resets node(s) (hard)" - c.arg_name "ACTION" - c.flag [:a, :action] - - c.action do |global_options, options, args| - @cmd = "omf-5.4 tell -c #{options[:c]} -t #{options[:t]} " - @cmd += "-a #{options[:a]} " if options[:a] - load_exp(@testbed_exp_path, global_options, options) - end -end - -on_error do |exception| - true -end - -pre do |global_options, command, options, args| - #opts = OmfCommon.load_yaml(config_file_name) if File.exist?(config_file_name) - #opts.delete("commands") - #global_options.merge!(opts) - - unless global_options[:uri] - help_now! "Incomplete options. Need communication URI" - end - - # Check version - if options[:check] - File.open(args[0], 'r') do |f| - f.read.chomp.match(/OMF_VERSIONS\W*=\W*(.*)/) - versions = $1 - unless versions && versions.split(',').include?(OmfCommon::PROTOCOL_VERSION) - raise StandardError, "Could not find compatibile protocol version number in your script" - end - end - end - - include OmfEc::DSL - - OmfEc.experiment.name = options[:experiment] if options[:experiment] - OmfEc.experiment.oml_uri = options[:oml_uri] if options[:oml_uri] - - @testbed_exp_path = File.join(OmfEc.lib_root, "omf_ec/backward/exp/testbed.rb") -end - -def setup_logging(global_options = {}) - if global_options[:xmpp] - require 'blather' - Blather.logger = logger - end - - unless global_options[:debug] - Logging.consolidate 'OmfCommon', 'OmfRc' - end - - if global_options[:colour] - Logging.logger.root.appenders.first.layout = Logging.layouts.pattern(date_pattern: '%F %T %z', - color_scheme: 'default', - pattern: '[%d] %-5l %c: %m\n') - end - - # FIXME this should go to common setup - if global_options[:log_file_dir] && File.exist?(File.expand_path(global_options[:log_file_dir])) - Logging.logger.root.add_appenders( - Logging.appenders.file( - "#{File.expand_path(global_options[:log_file_dir])}/#{OmfEc.experiment.id}.log", - :layout => Logging.layouts.pattern(:date_pattern => '%F %T %z', - :pattern => '[%d] %-5l %c: %m\n'))) - end - - if OmfEc.experiment.oml_uri - require 'oml4r/logging/oml4r_appender' - Logging.logger.root.add_appenders(Logging.appenders.oml4r('oml4r', :appName => 'omf_ec', :domain => "#{OmfEc.experiment.id}", :collect => "#{OmfEc.experiment.oml_uri}")) - end - - OmfCommon.load_logging_config(global_options[:log_config]) -end - -def load_exp(exp_path, global_options = {} , options = {}, properties = {}) - begin - if options[:inst_oml_uri] && options[:inst_oml_id] && options[:inst_oml_domain] - require 'oml4r' - 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)} ) - OmfCommon::Measure.enable if instrument_ec - end - - opts = { - communication: { url: global_options[:uri] }, - eventloop: { type: :em }, - logging: { - level: { default: global_options[:debug] ? 'debug' : 'info' }, - appenders: { - stdout: { - date_pattern: '%H:%M:%S', - pattern: '%d %-5l %c{2}: %m\n' - } - } - } - } - - opts[:communication][:auth] = { authenticate: true } if global_options[:cert] - - OmfCommon.init(:development, opts) do |el| - - setup_logging(global_options) - - OmfCommon.comm.on_connected do |comm| - info "OMF Experiment Controller #{OmfEc::VERSION} - Start" - info "Connected using #{comm.conn_info}" - info "Execute: #{exp_path}" - info "Properties: #{OmfEc.experiment.cmdline_properties}" - - if opts[:communication][:auth] && opts[:communication][:auth][:authenticate] - ec_cert = OmfCommon.load_credentials( - root_cert_dir: global_options[:root_cert_dir], - entity_cert: global_options[:cert], - entity_key: global_options[:key] - ) - - ec_cert.resource_id = OmfCommon.comm.local_address - OmfCommon::Auth::CertificateStore.instance.register(ec_cert) - end - - OmfEc.experiment.log_metadata("ec_version", "#{OmfEc::VERSION}") - OmfEc.experiment.log_metadata("exp_path", exp_path) - OmfEc.experiment.log_metadata("ec_pid", "#{Process.pid}") - - begin - include OmfEc::Backward::DefaultEvents - load exp_path - OmfEc::Experiment.start - rescue => e - OmfEc.experiment.log_metadata("state", "error") - error e.message - error e.backtrace.join("\n") - end - - comm.on_interrupted { OmfEc::Experiment.done } - end - end - rescue => e - logger.fatal e.message - logger.fatal e.backtrace.join("\n") - end -end - -exit run(ARGV) +OmfEc::Runner.new.run