From 45596d6fda896389e7689562960279d9abfe134b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Font=C3=A1n=20Mui=C3=B1os?= Date: Fri, 13 Mar 2009 17:13:14 +0000 Subject: [PATCH] im_ssh now uses new driver libraries git-svn-id: http://svn.opennebula.org/one/trunk@405 3034c82b-c49b-4eb3-8279-a7acafdc01c0 --- src/im_mad/im_ssh/one_im_ssh.rb | 278 +++++++++++++------------------- 1 file changed, 110 insertions(+), 168 deletions(-) diff --git a/src/im_mad/im_ssh/one_im_ssh.rb b/src/im_mad/im_ssh/one_im_ssh.rb index 2479f317d9..603fc4189c 100755 --- a/src/im_mad/im_ssh/one_im_ssh.rb +++ b/src/im_mad/im_ssh/one_im_ssh.rb @@ -31,14 +31,12 @@ end $: << RUBY_LIB_LOCATION -require 'pp' -require 'one_mad' -#require 'open3' +require 'pp' require 'digest/md5' require 'fileutils' -require 'thread' -require 'one_ssh' +require 'OpenNebulaDriver' +require 'CommandManager' DEBUG_LEVEL=ENV["ONE_MAD_DEBUG"] @@ -47,54 +45,29 @@ DEBUG_LEVEL=ENV["ONE_MAD_DEBUG"] ## ERROR, DEBUG=[0,1] - - -#################### -# SENSOR DEFINTION # -#################### - -class Sensor < SSHCommand - attr_accessor :name, :script, :value, :ok, :identifier - attr_accessor :script_hash - - # Sets remote script directory for all sensors - def self.set_script_dir(script_dir) - @@remote_dir=script_dir - end - - # Constructor, takes the name of the sensor and the script that provides that sensors +# This class holds the information of a IM probe and the methods +# to copy the script to the remote hosts and run it +class Sensor + attr_accessor :remote_dir + attr_reader :name, :script + def initialize(name, script) - @name=name || "" - @script=script || "" - @value=nil - @ok=false - + @name=name + @script=script + gen_identifier - @script_hash=gen_hash - super(script) end - # Runs the sensor in some host - def run(host=nil) - if !File.exists? @script - STDERR.puts("Script file does not exist: "+@script.to_s) - return - end + def execute(host, log_proc) + script_text=File.read @script + scr="'mkdir -p #{remote_dir};cat > #{remote_script};if [ \"x$?\" != \"x0\" ]; then exit 42;fi;chmod +x #{remote_script};#{remote_script}'" - create_remote_dir(host) - - if !send_script(host) - STDERR.puts("Can not send script to remote machine: "+host) - @value="Can not send script to remote machine: "+host - return - end - - (stdout, stderr)=execute(host, remote_script) - code=get_exit_code(stderr) - if code==0 + cmd=SSHCommand.run(scr, host, log_proc, script_text) + case cmd.code + when 0 # Splits the output by lines, strips each line and gets only # lines that have something - @value=stdout.split("\n").collect {|v| + value=cmd.stdout.split("\n").collect {|v| v2=v.strip if v2=="" nil @@ -103,35 +76,52 @@ class Sensor < SSHCommand end }.compact.join(",") - @ok=true - if @value.length==0 - @ok=false - @value=nil + when 42 + log_proc.call("Can not send script to remote machine: "+host) + nil + else + value="Could not execute remote script in " + + host + ": "+remote_script + log_proc.call(value) + nil + end + end + + def execute_old(host, log_proc) + if send_script(host, log_proc) + cmd=SSHCommand.run(@script, host, log_proc) + if cmd.code==0 + # Splits the output by lines, strips each line and gets only + # lines that have something + value=cmd.stdout.split("\n").collect {|v| + v2=v.strip + if v2=="" + nil + else + v2 + end + }.compact.join(",") + else + value="Could not execute remote script in " + + host + ": "+remote_script + log_proc.call(value) + nil end else - STDERR.puts("Could not execute remote script in " + - host + ": "+remote_script) - @value="Could not execute remote script in " + - host + ": "+remote_script + nil end end - def create_remote_dir(host) - execute(host, "mkdir -p " + @@remote_dir) - end - - # Copies the script to the remote machine - def send_script(host) - # TODO: only copy when necessary - (stdout, stderr)=exec_local_command("scp #{@script} #{host}:#{remote_script}") - code=get_exit_code(stderr) - - code==0 - end - - # Returns the path of the script in the remote machine - def remote_script - @@remote_dir+"/ne_im-"+identifier +private + + def send_script(host, log_proc) + cmd=LocalCommand.run("scp #{script} #{host}:#{@remote_dir}") + if cmd.code==0 + true + else + log_proc.call("Can not send script to remote machine: "+host) + false + end end # Generates an unique identifier using name of the sensor and its script @@ -139,53 +129,62 @@ class Sensor < SSHCommand id=@name+@script @identifier=Digest::MD5.hexdigest(id) end - - # Generates an MD5 hash of a file - def gen_hash - if !File.exists? @script - STDERR.puts("Script file does not exist: "+@script.to_s) - return nil - else - f=open(@script) - data=f.read - f.close - return Digest::MD5.hexdigest(data) - end + + # Returns the path of the script in the remote machine + def remote_script + @remote_dir+"/ne_im-"+@identifier end - def ok? - @ok - end end -################# -# SENSOR LOADER # -################# +class SensorList < Array + def initialize(config_file=nil) + super(0) + + @remote_dir='/tmp/ne_im_scripts' + + load_sensors(config_file) if config_file + end + + def execute_sensors(host, log_proc) + results=Array.new + self.each {|sensor| + results<0 - "MONITOR SUCCESS " + @number.to_s + " " + - good_results.collect{|s| s.value }.join(',') - else - bad_results=@actions.select{|s| !s.ok? && s.value } - err_text="Unknown error" - err_text=bad_results[0].value.to_s if bad_results.length>0 - "MONITOR FAILURE " + @number.to_s + " " + err_text - end - end -end - - -########## -# IM MAD # -########## - -class IM < ONEMad - include SSHActionController - - def initialize(sensors=nil) - super(3, 4) + @sensor_list=SensorList.new(config_file) - if DEBUG_LEVEL and !DEBUG_LEVEL.empty? - set_logger(STDERR,DEBUG_LEVEL) - end - - if sensors - @sensors=sensors - else - @sensors=SensorList.new - end - - init_actions - end - - def action_init(args) - STDOUT.puts "INIT SUCCESS" - STDOUT.flush - log("INIT SUCCESS",DEBUG) + # register actions + register_action(:MONITOR, method("action_monitor")) end - def action_monitor(args) - action=PollAction.new(args[1], args[2], @sensors) - action.callback=lambda {|actions,number| - result=get_result(actions, number) - STDOUT.puts result - STDOUT.flush - log(result,DEBUG) - } - send_ssh_action(action) - end - - def get_result(actions, number) - good_results=actions.select{|s| s.ok? } - - if good_results.length>0 - "MONITOR SUCCESS " + number.to_s + " " + - good_results.collect{|s| s.value }.join(',') + def action_monitor(number, host) + results=@sensor_list.execute_sensors(host, log_method(number)) + information=results.select{|res| res && !res.empty? }.join(",") + if information and !information.empty? + send_message("MONITOR", RESULT[:success], number, information) else - bad_results=actions.select{|s| !s.ok? && s.value } - err_text="Unknown error" - err_text=bad_results[0].value.to_s if bad_results.length>0 - "MONITOR FAILURE " + number.to_s + " " + err_text + send_message("MONITOR", RESULT[:failure], number, + "Could not monitor host #{host}.") end end + end - -sensors=SensorList.new im_conf=ARGV[0] if !im_conf @@ -285,9 +230,6 @@ if !im_conf end im_conf=ETC_LOCATION+im_conf if im_conf[0] != ?/ -sensors.load_sensors(im_conf) - -im=IM.new(sensors) - -im.loop +im=InformationManager.new(im_conf, 15) +im.start_driver