class OpenNebulaDriver
This class provides basic messaging and logging functionality to implement OpenNebula
Drivers. A driver is a program that specialize the OpenNebula
behavior by interfacing with specific infrastructure functionalities.
A Driver inherits this class and only has to provide methods for each action it wants to receive. The method must be associated with the action name through the register_action function
Attributes
@return [String] Base path for scripts
@return [String] Path for scripts
@return [String] Base path for scripts
@return [String] Path for scripts
Public Class Methods
Initialize OpenNebulaDriver
object
@param [String] directory path inside the remotes directory where the
scripts are located
@param [Hash] options named options to change the object’s behaviour @option options [Number] :concurrency (10) max number of threads @option options [Boolean] :threaded (true) enables or disables threads @option options [Number] :retries (0) number of retries to copy scripts
to the remote host
@option options [Hash] :local_actions ({}) hash with the actions
executed locally and the name of the script if it differs from the default one. This hash can be constructed using {parse_actions_list}
ActionManager::new
# File lib/OpenNebulaDriver.rb, line 52 def initialize(directory, options = {}) @options={ :concurrency => 10, :threaded => true, :retries => 0, :local_actions => {}, :timeout => nil }.merge!(options) super(@options[:concurrency], @options[:threaded]) @retries = @options[:retries] @timeout = @options[:timeout] # Set default values initialize_helper(directory, @options) register_action(:INIT, method('init')) end
This function parses a string with this form:
'deploy,shutdown,poll=poll_ganglia, cancel '
and returns a hash:
{"POLL"=>"poll_ganglia", "DEPLOY"=>nil, "SHUTDOWN"=>nil, "CANCEL"=>nil}
@param [String] str imput string to parse @return [Hash] parsed actions
# File lib/OpenNebulaDriver.rb, line 162 def self.parse_actions_list(str) actions = {} str_splitted = str.split(/\s*,\s*/).map {|s| s.strip } str_splitted.each do |a| m=a.match(/([^=]+)(=(.*))?/) next unless m action=m[1].upcase if m[2] script=m[3] script.strip! if script else script=nil end actions[action]=script end actions end
Public Instance Methods
Calls remotes or local action checking the action name and @local_actions. Optional arguments can be specified as a hash
@param [String] parameters arguments passed to the script @param [Number, String] id action identifier @param [String] host hostname where the action is going to be executed @param [String, Symbol] aname name of the action @param [Hash] ops extra options for the command @option ops [String] :stdin text to be writen to stdin @option ops [String] :script_name default script name for the action,
action name is used by defaults
@option ops [Bool] :respond if defined will send result to ONE core @option ops [Bool] :base64 encode the information sent to ONE core @option ops [Bool] :zip compress the information sent to ONE core
# File lib/OpenNebulaDriver.rb, line 86 def do_action(parameters, id, host, aname, ops = {}) options = { :stdin => nil, :script_name => nil, :respond => true, :ssh_stream => nil, :base64 => false, :zip => false, :no_extra_params => false }.merge(ops) params = parameters params = "#{params} #{id} #{host}" unless options[:no_extra_params] command = action_command_line(aname, params, options[:script_name]) # if options[:is_local] is not specified (nil) # we rely uniquely in actions_is_local? if action_is_local?(aname) or options[:is_local] stdin = Base64.strict_encode64(options[:stdin].to_s) execution = LocalCommand.run(command, log_method(id), stdin, @timeout) elsif options[:ssh_stream] if options[:stdin] cmdin = "cat << EOT | #{command}" stdin = "#{options[:stdin]}\nEOT\n" else cmdin = command stdin = nil end execution = options[:ssh_stream].run(cmdin, stdin, command, @timeout) else execution = RemotesCommand.run(command, host, @remote_scripts_base_path, log_method(id), options[:stdin], @retries, @timeout) end result, info = get_info_from_execution(execution) if options[:respond] info = Zlib::Deflate.deflate(info, Zlib::BEST_COMPRESSION) if options[:zip] info = Base64.strict_encode64(info) if options[:base64] send_message(aname, result, id, info) end [result, info] end
Start the driver. Reads from STDIN and executes methods associated with the messages
# File lib/OpenNebulaDriver.rb, line 146 def start_driver Thread.new { loop } start_listener end
Private Instance Methods
# File lib/OpenNebulaDriver.rb, line 187 def init send_message('INIT', RESULT[:success]) end
# File lib/OpenNebulaDriver.rb, line 191 def loop Kernel.loop do exit!(-1) if STDIN.eof? str = STDIN.gets next unless str args = str.split(/\s+/) next if args.empty? if args.first.empty? STDERR.puts "Malformed message: #{str.inspect}" next end action = args.shift.upcase.to_sym if args.empty? || !args[0] action_id = 0 else action_id = args[0].to_i end if action == :DRIVER_CANCEL cancel_action(action_id) log(action_id, "Driver command for #{action_id} cancelled") else trigger_action(action, action_id, *args) end end end