机房停电自动关机脚本, 机房有UPS,但只能撑30分钟吧,


脚本指定时间去ping两台机器, 如果都超时,就开始关机


脚本放在 100.33 电脑中的VM里面


#!/usr/bin/ruby
require 'net/ssh'
require 'net/telnet'
ip = ["192.168.100.20","192.168.100.21"]
list_srv = '/root/machine.txt'
$hash = {}
$log = ''
def mailer(subject,main=subject)
msgstr = <
To: Bian 
Subject: #{subject}
#{main}
END_OF_MESSAGE
        acct = '[email protected]'
        domain = "163.com"
        pass = 'x3s2x2'
        begin
                Net::SMTP.start('smtp.163.com', 25, domain, acct, pass, :login) { |smtp|
                                smtp.send_message msgstr,'[email protected]','[email protected]'
                }
        rescue
        end
end
def check_alive(ip)
result = []
ip.each{|x| result << `ping #{x} -c 4 | grep ttl | wc -l`.to_i }
return result
end
def close_win(whost,wuser,wpass)
whost == '192.168.100.33'? time = 240 : time = 3
begin
     `net rpc shutdown -s -f -t #{time} -I #{whost} -U #{wuser}%#{wpass}`
rescue
end
end
def close_ubuntu(host,user,pass)
begin
        Net::SSH.start(host, user, :password => pass) { |session|
                session.open_channel { |channel|
                channel.request_pty
                channel.exec("sync; sync; sync; sudo -p 'Password' init 0") { |ch, success|
                        abort "could not execute command" unless success
                channel.on_data { |ch, data|    #result
                        if data =~ /Password/
                                channel.send_data(pass + "\n")
                        end
                }
                }
                }
                #session.loop
        }
rescue
end
end
def close_centos(ip,user,pass)
begin
        Net::SSH.start(ip, user, :password => pass) {|ssh|
        ssh.exec!("sync; sync; sync; init 0")
        }
rescue
end
end
def close_vm(ip,user,pass,type,vm_name)
        if type == "vm"
                cmd = "sync; sync; sync; halt"
        else
                cmd = "esxcli vm process kill --type=soft --world-id=`esxcli vm process list |
                                grep -A 1 -E '^#{vm_name}' | tail -1 | awk '{print $3}'`"
        end
begin
        Net::SSH.start(ip, user, :password => pass) {|ssh|
        ssh.exec!("#{cmd}")
        }
rescue
end
end
def     drbd(ip,user,pass) #check DRBD Pri or Sec
begin
        Net::SSH.start(ip, user, :password => pass ) { |ssh|
        result = ssh.exec!("ip a | grep '192.168.100.50' | wc -l")
        return result.to_i
    }
rescue
end
end
def close(type)
$hash.each { |x,y|
        if y[3].strip == type
        case y[2].strip
                when 'win'
                        close_win(x.strip, y[0].strip, y[1].strip)
                when 'centos'
                        close_centos(x.strip, y[0].strip, y[1].strip)
                when 'ubuntu'
                        if type == 'c'
                                if drbd(x.strip, y[0].strip, y[1].strip) == 1 #DRBD is Pri
                                        redo
                                else
                                        close_ubuntu(x.strip, y[0].strip, y[1].strip)
                                end
                        else
                                close_ubuntu(x.strip, y[0].strip, y[1].strip)
                        end
                when 'vm'
                        if type == 'a'
                                close_vm(x.strip, y[0].strip, y[1].strip, "srv", "BeiJingHWA")
                        elsif type == 'b'
                                close_vm(x.strip, y[0].strip, y[1].strip, "srv", "Panabit")
                        else
                                close_vm(x.strip, y[0].strip, y[1].strip,"vm", "")
                        end
                end
        sleep 3
        end
}
end
def check(type)
        $hash.each {|x,y|
                if y[3].strip == type
                        begin
                                Net::Telnet::new("Host" => x.strip,"Port" => y[4].strip.to_i, "Telnetmode" => false)
                                $log = $log + "#{x.strip} is PowerON " + Time.now.strftime("%Y-%m-%d %k:%M")
                        rescue
                                $log = $log + "#{x.strip} is PowerOFF " + Time.now.strftime("%Y-%m-%d %k:%M")
                        end
                end
        }
end
def log(str)
aFile = File.new(Dir.pwd + Time.now.strftime("%Y-%m-%d") + ".log","w")
       aFile.puts str
aFile.close
end
#============== start close server
File.open(list_srv,'r').each {|x|
        $hash[x.split(',')[0]] = [x.split(',')[1], x.split(',')[2], x.split(',')[3], x.split(',')[4], x.split(',')[5]]
        #ip,user,pass,os_type,close_type,check_port
}
loop do
result = check_alive(ip)
        if (result[0] == 0) && (result[1] == 0)
                mailer("Power Notice", "Abnormal power")
                break
        elsif (result[0] == 0) || (result[1] == 0)
                mailer("Device Err", "One Device Maybe Down")
                Process.exit(0)
        end
        sleep 40
end
#first
close('a')
sleep 120
check('a')
#second
close('b')
sleep 30
check('b')
#third
close('c')
sleep 180
check('c')
#vm
close('d')
sleep 60
check('d')
log($log)
sleep 5
#close vcenter
close_win("192.168.100.33", $hash['192.168.100.33'][0], $hash['192.168.100.33'][1])
exec('sync; sync; sync; init 0')