$:.unshift File.expand_path(File.dirname(__FILE__)) $:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'installer', 'utils')) require 'rubygems' require 'fog' require 'net/http' require 'constants' require 'readline' # METHODS # cmd # easily issue system commands in a clear way def cmd(cmd) puts cmd system(cmd) end #cmd # ssh_cmd # More easily issue commands over the ssh connection. def ssh_cmd(cmd) puts cmd puts @ssh.run(cmd)[0].stdout end #ssh_cmd # compile_stack_info # Fills in all necessary information which is stack specific def compile_stack_info # User is stack specific but not to # be included in the fog creation hash @user = @stack[:user] @stack.delete :user # This part of the package name will always be the same local_file = "#{`pwd`.strip}/pkg/" # Append the rest of the file name according to distribution if @user == 'ubuntu' @dist = { :package => "rhoconnect_#{Constants::RC_VERSION}_all.deb", :local_file => "#{local_file}rhoconnect_#{Constants::RC_VERSION}_all.deb", :pkg_mgr => 'dpkg', :pkg_type => 'DEB', :pkg_repo => 'apt-get -y', :deps => Constants::DEB_DEPS } elsif @user == 'root' @dist = { :package => "rhoconnect-#{Constants::RC_VERSION}.noarch.rpm", :local_file => "#{local_file}rhoconnect-#{Constants::RC_VERSION}.noarch.rpm", :pkg_mgr => 'rpm', :pkg_type => 'RPM', :pkg_repo => 'yes | yum', :deps => Constants::RPM_DEPS } else puts "Incorrect user name" exit end #i end #compile_stack_info # create_ec2_instance # Generates the Fog object and creates a new ec2 instance. def create_ec2_instance make_fog start_new_instance end #create_ec2_instance # get_access_keys # Retrieves the access key and secret access key from the above specified file. def get_access_keys lines = IO.readlines Constants::ACCESS_KEY_FILE @access_key = lines.first.strip @secret_access_key = lines.last.strip end #get_access_keys # make_fog # Generates the Fog object used to create the new ec2 instance. def make_fog get_access_keys @fog = Fog::Compute.new( :provider => 'AWS', :region => Constants::REGION, :aws_access_key_id => @access_key, :aws_secret_access_key => @secret_access_key ) end #make_fog # start_new_instance # Creates a new ec2 instance as per the given stack. def start_new_instance puts "Creating new instance..." @server = @fog.servers.create(@stack) @server.wait_for { print "."; STDOUT.flush; ready? } puts if @server.ready? # wait for all services to start on remote VM puts "Waiting #{Constants::SLEEP} seconds for services to start on remote VM..." Constants::SLEEP.times do sleep 1 print "." STDOUT.flush end #do puts # save important instance information @host = @server.dns_name @server_id = @server.id else puts "Server timed out." exit end #if end #start_new_instance # establish_ssh_connection # Establishes the ssh connection needed to issue commands to the remote machine. def establish_ssh_connection @ssh = Fog::SSH.new( @host, @user, :keys => Constants::SSH_KEY ) end #establish_ssh_connection # establish_scp_connection # Establishes a gateway through which to transfer data def establish_scp_connection @scp = Fog::SCP.new( @host, @user, :keys => Constants::SSH_KEY ) end #create_scp_connection # transfer # transfers given data to remote machine via scp def transfer(local_data, remote_data) puts "Attempting file transfer via SCP" puts "Transferring #{local_data} to #{remote_data}..." @scp.upload( local_data, remote_data ) do |cd, name, sent, total| print "\r#{name}: #{(sent.to_f * 100 / total.to_f).to_i}%" end #do puts end #establish_scp_connection # transfer_rhoconnect # Transfers the rhoconnect package over SCP def transfer_rhoconnect transfer @dist[:local_file], @dist[:remote_home] end #transfer_rhoconnect # destroy_ec2_instance # Terminates the current ec2 instance def destroy_ec2_instance @server.destroy puts "Terminating Instance." end #destroy_ec2_instance # install_dependencies # Installs all dependant packages on the remove machine def install_dependencies dep_install_string = "sudo #{@dist[:pkg_repo]} install" @dist[:deps].each do |dep| dep_install_string << " #{dep}" end #do ssh_cmd "sudo #{@dist[:pkg_repo]} update" ssh_cmd dep_install_string puts end #install_dependencies # install_package # Issues commands to the remote machine to start the installation def install_package install_dependencies ssh_cmd "sudo #{@dist[:pkg_mgr]} -i #{@dist[:package]}" puts end #install_package def start_servers attempts = 0 while @ssh.run("pgrep redis")[0].stdout.strip == "" ssh_cmd "sudo /etc/init.d/redis start" attempts += 0 end #while puts "Redis start took #{attempts} attempts" puts attempts = 0 while @ssh.run("pgrep nginx")[0].stdout.strip == "" ssh_cmd "sudo /etc/init.d/nginx start" attempts += 0 end #while puts "Nginx start took #{attempts} attempts." puts puts "Waiting #{Constants::SLEEP} seconds for servers to initialize" Constants::SLEEP.times do sleep 1 print '.' STDOUT.flush end # do puts end # start_servers def check_rc_service request = Net::HTTP.get_response(@host, '/console') puts "Host: #{@host}" puts "Code: #{request.code} Message: #{request.message}" if request.code == '200' puts "Rhoconnect service up!" else puts "Rhoconnect service down :(" end #if end #check_rc_service def compute_time(start_time, end_time) time_delta = (end_time - start_time) if time_delta >= 60 time_delta /= 60 time_units = 'minute' if time_delta > 1 time_units << 's' end #if else time_units = 'seconds' end #if "\nTest completed in #{time_delta} #{time_units}\n" end #compute_time # SCRIPT # Test Package installations Constants::STACKS.each do |stack| start_time = Time.now begin @stack = stack compile_stack_info puts puts "================================================" puts "Now starting test of #{@dist[:pkg_type]} package" puts "================================================" puts create_ec2_instance # Establish connections establish_ssh_connection @dist[:remote_home] = @ssh.run("echo ~")[0].stdout.strip establish_scp_connection # Transfer the Rhoconnect package to the remote machine transfer_rhoconnect puts "Installing rhoconnect package.\n" + "This may take a while...\n\n" install_package # Start the redis and nginx servers on the remote machine start_servers # Check the status of the rhoconnect service check_rc_service end_time = Time.now puts compute_time(start_time, end_time) rescue => e puts "OH NOEZ, Exception!!" puts e.inspect puts e.backtrace ensure if @server != nil destroy_ec2_instance end #if end #begin end #do