Skip to content

Instantly share code, notes, and snippets.

@rwheaton
Created March 27, 2012 19:38
Show Gist options
  • Save rwheaton/2219584 to your computer and use it in GitHub Desktop.
Save rwheaton/2219584 to your computer and use it in GitHub Desktop.
example rightscript
#!/bin/env ruby
#
# Copyright (c) 2007-2011 RightScale, Inc, All Rights Reserved Worldwide.
#
# Contacts and configures an HAProxy server for user with a generic apache application
# LB_APPLISTENER_NAME -- specifies which HAProxy server pool to use
# LB_BACKEND_NAME -- A unique name for each back end e.g. (AMI_INSTANCE_ID)
# MAX_CONN_PER_SERVER -- Maximum number of connections per server
# HEALTH_CHECK_URI --
# APP_PORT -- Port which the LB connect to the app web server for health check
require 'rubygems'
require 'yaml'
require 'resolv'
require 'timeout'
require 'json'
#Temporary, require. These will be automatically passed in soon.
os_info=`lsb_release -a`.downcase + `uname`.downcase
if os_info =~ /ubuntu/
 ENV['RS_DISTRO']="ubuntu"
 apache="apache"
 ubuntu = true
 centos = false
elsif os_info =~ /centos/
 ENV['RS_DISTRO']="centos"
 apache="httpd"
 centos = true
 ubuntu = false
end
# Set the default port for the application server.
port = ENV['APP_PORT']
#Escape the 4 problematic shell characters: ", $, `, and \ to get through the ssh command correctly
def shell_escape(string)
 return string.gsub(/\\/,"\\\\\\").gsub(/\"/,"\\\"").gsub(/\$/,"\\\$").gsub(/\`/,"\\\\\`")
end
# Connect server machine to load balancer to start receiving traffic
applistener  = ENV['LB_APPLISTENER_NAME']
backend_name = ENV['LB_BACKEND_NAME']
case ENV['LB_BACKEND_IP']
when "private"
 this_backend = ENV['RS_PRIVATE_IP']
 puts "Registering the private ip: $this_backend"
when "public"
 this_backend = ENV['RS_PUBLIC_IP']
 puts "Registering the public ip: $this_backend"
else
 this_backend = ENV['RS_PRIVATE_IP']
 puts "Unknown IP type, using ip: #{this_backend}"
end
# Use cookies?
sess_sticky = "#{ENV['OPT_SESSION_STICKINESS']}".downcase
if(sess_sticky && sess_sticky.match(/^(true|yes|on)$/))
 cookie_options = "-c #{ENV['LB_BACKEND_NAME']}"
end
# How many conns do we tell the LB to bring to the AJP port?
max_conn_per_svr = ENV['MAX_CONN_PER_SERVER'] || 255
# Connect the app to all running instances of the lb host
addrs = Array.new
tag_query_output = `rs_tag --query "lb:set=#{ENV['LB_SET']}"`
puts "*** All LBs in the deployment tagged as part of the \"#{ENV['LB_SET']}\" lb set: #{tag_query_output}"
parsed_json= JSON.parse(tag_query_output)
parsed_json.each { |node|
 node[1]["tags"].each { |tag|
   if ( tag =~ /lb:ip=(.+)/ )
     addrs << $1
     puts "*** Found LB with IP: "+$1
   end
 }
}
puts "Found  #{addrs.length} addresses for lb set: #{ENV['LB_SET']}"
exit(-1) if addrs.length == 0
successful=0
addrs.each do |addr|
  begin
   addr_name=Resolv.getname(addr)
   addr_new=Resolv.getaddress(addr_name) if addr_name =~ /^ec2.*amazonaws.com$/
   addr=addr_new if addr_new =~ /^10\./
 rescue => e
   puts e.message+", moving on..."
 end
 puts ">>>>>>>Attaching app to host #{addr} <<<<<<<<<<<<<<"
 # Using the default config file...no cookie persistence...and health checks
 #/opt/rightscale/lb/bin/haproxy_config_server.rb  -a add -w -l $LB_APPLISTENER -s $LB_BACKEND_NAME -t $BACKEND_TARGET -k on -e "inter 3000 rise 2 fall 3 maxconn 3"
 sshcmd = "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no root@#{addr}"
 cfg_cmd="/opt/rightscale/lb/bin/haproxy_config_server.rb"
 target="#{this_backend}:#{port}"
 args= "-a add -w -l \"#{applistener}\" -s \"#{backend_name}\" -t \"#{target}\" #{cookie_options} -e \" inter 3000 rise 2 fall 3 maxconn #{max_conn_per_svr}\" "
 args += " -k on " if ENV['HEALTH_CHECK_URI'] != nil && ENV['HEALTH_CHECK_URI'] != ""
 cmd = "#{sshcmd} #{cfg_cmd} #{shell_escape(args)}"
 puts cmd
 timeout=60*5 #@ 5min
 begin
   status = Timeout::timeout(timeout) do
    while true  
       response = `#{cmd}`
   puts response #for debugging...
   break if response.include?("Haproxy restart sucessful")
       break if response.include?("Restart not required")
       puts "Retrying..."
       sleep 10
     end
   end
 rescue Timeout::Error => e
   puts "ERROR: Timeout after #{timeout/60} minutes."
   next
 end  
 
 successful += 1
end
if( successful != addrs.length )
 puts "Failure, only #{successful} out of #{addrs.length} lb hosts could be connected"
 exit(-1)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment