机房停电自动关机脚本, 机房有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 = <<END_OF_MESSAGE From: SVN <[email protected]> To: Bian <[email protected]> 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')