Created
December 15, 2009 04:48
-
-
Save plukevdh/256702 to your computer and use it in GitHub Desktop.
Quick and to the point IP Failover
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/ruby | |
# | |
# File: failoverd.rb | |
# Description: Daemon to handle failover and restart | |
# Date: 12-14-2009 - Luke van der Hoeven | |
# | |
# Credit: Based on Patrick Hennessy's ipfaild.pl script | |
# (http://git.pathennessy.com/cgi-bin/gitweb.cgi?p=linux-scripts.git;a=blob;f=ipfaild.pl;hb=HEAD) | |
# | |
require 'rubygems' | |
require 'daemons' | |
require 'syslog' | |
require 'ping' | |
require 'action_mailer' | |
## For email notifications ## | |
ActionMailer::Base.delivery_method = :smtp | |
ActionMailer::Base.smtp_settings = { | |
:address => "ptvlmail2.hargray.org", | |
:port => 25 | |
} | |
class Emailer < ActionMailer::Base | |
def failover | |
subject "Primary Production Server Down!!" | |
from "[email protected]" | |
recipients "[email protected]" | |
body "ITWEBPUB1 is down. Failing over to ITWEBPUB2.\nPlease inspect the primary server and restore order to the galaxy." | |
end | |
end | |
## File IO Paths ## | |
@program_name = "failoverd" | |
@daemon_lock_file = "/var/run/#{@program_name}/#{@program_name}.lock" | |
## Executable paths ## | |
@ifconfig = '/sbin/ifconfig' | |
@send_arp = '/usr/sbin/send_arp' | |
@apache2ctl = '/usr/sbin/apachectl' | |
## Configuration params ## | |
@ping_timeout = 1 | |
@sleep_time = 2 | |
@fail_threshold | |
@missed = 0 | |
@is_live = false | |
@active = true | |
## Server config ## | |
@other_server = "itwebpub1" | |
@this_mac = "00:1E:C9:5C:A7:9B" | |
@ip_records = [ | |
{:name => "foobar", :ip => "192.168.120.57", :dev => "eth0:0", :mask => "255.255.255.0" } | |
] | |
#function for loading the VIP | |
def ifconfig_down | |
for record in @ip_records | |
Syslog.info("Running: #{@ifconfig} #{record[:dev]} down") | |
unless system("#{@ifconfig} #{record[:dev]} down") | |
Syslog.info("Error: #{$!} \"#{@ifconfig} #{record[:dev]} down\" failed.") | |
end | |
end | |
end | |
Daemons.run_proc('failoverd.rb') do | |
f = File.new(@daemon_lock_file, 'w+') | |
if(f == 0) | |
warn "#{@program_name}: Couldn't open #{@daemon_lock_file}" | |
exit(0) | |
end | |
#put the process id into a the pid file | |
f.write Process.pid | |
#open the system log | |
Syslog.open(@program_name, Syslog::LOG_PID, Syslog::LOG_DAEMON) | |
#handle all termination signals | |
Signal.trap("HUP") do | |
Syslog.info("#{@program_name} caught SIGHUP") | |
@active = false | |
end | |
Signal.trap("INT") do | |
Syslog.info("#{@program_name} caught SIGINT") | |
@active = false | |
end | |
Signal.trap("QUIT") do | |
Syslog.info("#{@program_name} caught SIGQUIT") | |
@active = false | |
end | |
Signal.trap("TERM") do | |
Syslog.info("#{@program_name} caught SIGTERM") | |
@active = false | |
end | |
#initialize by releasing the VIP | |
ifconfig_down | |
#main loop | |
while @active | |
unless Ping.pingecho(@other_server, @ping_timeout) #no response | |
@missed += 1 | |
else | |
if @missed > @fail_threshold | |
ifconfig_down #primary is back, release VIP | |
@is_live = false | |
@missed = 0 | |
end | |
end | |
if @missed == @fail_threshold and !@is_live | |
@is_live = true #primary is down, load VIP | |
for record in @ip_records | |
Syslog.info("Running: #{@ifconfig} #{record[:dev]} #{record[:ip]} netmask #{record[:mask]}") | |
unless system("#{@ifconfig} #{record[:dev]} #{record[:ip]} netmask #{record[:mask]}") | |
Syslog.info("Error: #{$!} \"#{@ifconfig} #{record[:dev]} #{record[:ip]} netmask #{record[:mask]}") | |
end | |
#notify IP tables | |
Syslog.info("Running: #{@send_arp} #{record[:ip]} #{@this_mac} #{record[:ip]} ff:ff:ff:ff:ff:ff") | |
unless system("#{@send_arp} #{record[:ip]} #{@this_mac} #{record[:ip]} ff:ff:ff:ff:ff:ff") | |
Syslog.info("Error: #{$!} \"#{@send_arp} #{record[:ip]} #{@this_mac} #{record[:ip]} ff:ff:ff:ff:ff:ff\"") | |
end | |
end | |
#restart apache | |
Syslog.info("Running: #{@apache2ctl} -k restart") | |
unless system("#{@apache2ctl} -k restart") | |
Syslog.info("Error: #{$!} \"#{@apache2ctl} -k restart\"") | |
end | |
#send email notification of server down | |
Emailer.deliver_failover | |
end | |
sleep @sleep_time | |
end | |
#release VIP if shutting down failover | |
ifconfig_down | |
Syslog.close | |
f.close | |
exit(0) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#run with the command | |
#only needs to be run on the backup server | |
[ruby |./]failoverd.rb start|stop|restart|run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment