Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

cleanup, instance sizes, awesome new role_from_security_group method,…

… grabbing of the public key from newly launched instances
  • Loading branch information...
commit 6fdcce548248fbf2c80f07e69d2c4a270ffca020 1 parent e7045f5
@jnewland authored
View
1  lib/capsize/configuration.rb
@@ -51,6 +51,7 @@
set :image_id, nil
set :min_count, 1
set :max_count, 1
+ set :instance_type, 'm1.small'
# FIXME : Breaks loading of this file and tests
# set :key_name, "#{application}"
# set :queue_name, "#{application}"
View
50 lib/capsize/ec2.rb
@@ -175,7 +175,7 @@
else
begin
- dns_name = capsize_ec2.get_dns_name_from_instance_id(:instance_id => capsize.get(:instance_id))
+ dns_name = capsize_ec2.hostname_from_instance_id(capsize.get(:instance_id))
rescue Exception => e
puts "The attempt to get the DNS name for your instance failed with the error : " + e
end
@@ -188,7 +188,7 @@
# For the ultra paranoid who are concerned about man-in-the-middle attacks you
# may want to do ssh manually, and perhaps not use no-password public key auth.
#
- # example connect : ssh -o StrictHostKeyChecking=no -i config/myappkey.key root@ec2-72-44-51-000.z-1.compute-1.amazonaws.com
+ # example connect : ssh -o StrictHostKeyChecking=no -i config/id_rsa-myappkey root@ec2-72-44-51-000.z-1.compute-1.amazonaws.com
puts "Trying to connect with host with local shell command:"
puts "ssh -o StrictHostKeyChecking=no -i #{key_file} root@#{dns_name}"
puts "--\n"
@@ -210,8 +210,8 @@
capsize_ec2.print_instance_description(response)
instance_id = response.reservationSet.item[0].instancesSet.item[0].instanceId
- puts "You should be able to connect within a minute or two to this new instance via SSH (using public key authentication) with:\n"
- puts "cap ec2:instances:ssh INSTANCE_ID='#{instance_id}'"
+ puts "SSH:"
+ puts "cap -s instance_id='#{instance_id}' ec2:instances:ssh"
puts ""
# TODO : Tell the user exactly what instance info they need to put in their deploy.rb
@@ -454,7 +454,7 @@
ports.each { |port|
begin
capsize_ec2.authorize_ingress({:group_name => capsize.get(:group_name), :from_port => "#{port}", :to_port => "#{port}"})
- puts "Firewall ingress granted for :group_name => #{capsize.get(:group_name)} on port #{port}"
+ puts "Firewall ingress granted for #{capsize.get(:group_name)} on port #{port}"
rescue EC2::InvalidPermissionDuplicate => e
puts "The firewall ingress rule you specified for group name \"#{capsize.get(:group_name)}\" on port #{port} was already set (EC2::InvalidPermissionDuplicate)."
# Don't re-raise this exception
@@ -519,46 +519,6 @@
end
-
- # CAPSIZE TASKS
- #########################################
-
-
- # TODO : GET THIS TASK WORKING WITH NEW AMAZON-EC2
- # TODO : What is the story with this on a cross platform basis? Will the commands run an any linux? OS X? We know its not windows...
- # TODO : ADD FULL CAP -E DOCS HERE
- # TODO : This doesn't use Net::SSH, but rather shells out to SSH to access the host w/ private key auth. Should it?
- desc <<-DESC
- Creates a secure root password, adds a user, and gives that user sudo privileges on the specified INSTANCE_ID.
- DESC
- task :setup_user do
- set :user, fetch(:user) {`whoami`.chomp}
- puts "\nConnecting to #{aws_hostname}..."
- puts "\nPlease create a secure root password"
- system "ssh -o StrictHostKeyChecking=no -i #{aws_private_key_path} root@#{aws_hostname} passwd"
- puts "\nCreating #{user} user"
- system "ssh -o StrictHostKeyChecking=no -i #{aws_private_key_path} root@#{aws_hostname} 'useradd -m -G wheel -s /bin/bash #{user} && passwd #{user}'"
- puts "Adding wheel group to sudoers"
- system "ssh -o StrictHostKeyChecking=no -i #{aws_private_key_path} root@#{aws_hostname} 'chmod 640 /etc/sudoers; echo -e \"#{user}\tALL=(ALL)\tALL\" >> /etc/sudoers;chmod 440 /etc/sudoers'"
- puts "Ensuring #{user} has permissions on #{deploy_to}"
- system "ssh -o StrictHostKeyChecking=no -i #{aws_private_key_path} root@#{aws_hostname} 'umask 02 && mkdir -p #{deploy_to} && chown #{user}:wheel #{deploy_to}'"
- end
-
end # end namespace :ec2
- # TODO : Should this method remain?
- #
- # This helper method is called in instances:run to set the default roles to
- # the newly spawned EC2 instance.
- #
- # no desc "" is provided to ensure this method does not show up in 'cap -T'
- # listing as it generally would not be called directly.
- # Hack? : This method must be defined outside of a namespace or it will raise an exception!
- #
- #task :set_default_roles_to_target_role do
- # role :web, dns_name
- # role :app, dns_name
- # role :db, dns_name, :primary => true
- #end
-
end # end Capistrano::Configuration.instance.load
View
83 lib/capsize/ec2_plugin.rb
@@ -18,23 +18,60 @@ module CapsizeEC2
#########################################
- def get_dns_name_from_instance_id(options = {})
- amazon = connect()
- options = {:instance_id => ""}.merge(options)
+ def hostname_from_instance_id(instance_id = nil)
+ raise Exception, "Instance ID required" if instance_id.nil? || instance_id.empty?
- raise Exception, "Instance ID required" if options[:instance_id].nil? || options[:instance_id].empty?
+ amazon = connect()
- response = amazon.describe_instances(:instance_id => options[:instance_id])
+ response = amazon.describe_instances(:instance_id => instance_id)
return dns_name = response.reservationSet.item[0].instancesSet.item[0].dnsName
end
+ def hostnames_from_instance_ids(ids = [])
+ ids.collect { |id| hostname_from_instance_id(id) }
+ end
+
+ def hostnames_from_group(group_name = nil)
+ hostnames = []
+ return hostnames if group_name.nil?
+ instances = describe_instances
+ return hostnames if instances.nil?
+ return hostnames if instances.reservationSet.nil?
+ instances.reservationSet.item.each do |reservation|
+ hostname = nil
+ matches = false
+ running = false
+ unless reservation.groupSet.nil?
+ reservation.groupSet.item.each do |group|
+ matches = group.groupId == group_name
+ end
+ end
+
+ unless reservation.instancesSet.nil?
+ reservation.instancesSet.item.each do |instance|
+ hostname = instance.dnsName
+ running = (!instance.instanceState.nil? && (instance.instanceState.name == "running"))
+ end
+ end
+ hostnames << hostname if matches and running
+ end
+ return hostnames
+ end
+
+ def role_from_security_group(role, security_group, *args)
+ options = args.last.is_a?(Hash) ? args.pop : {}
+ options = {:user => 'root', :ssh_options => { :keys => [capsize_ec2.get_key_file] }}.merge(options)
+ role(role, options) do
+ hostnames_from_group(security_group)
+ end
+ end
# build the key file path from key_dir and key_file
def get_key_file(options = {})
options = {:key_dir => nil, :key_name => nil}.merge(options)
key_dir = options[:key_dir] || get(:key_dir) || get(:capsize_secure_config_dir)
key_name = options[:key_name] || get(:key_name)
- return key_file = [key_dir, key_name].join('/') + '.key'
+ return key_file = [key_dir, "id_rsa-" + key_name].join('/')
end
@@ -60,8 +97,6 @@ def describe_keypairs(options = {})
amazon.describe_keypairs(:key_name => options[:key_name])
end
-
- # TODO : Is there a way to extract the 'puts' calls from here and make this have less 'view' code?
#sets up a keypair named options[:key_name] and writes out the private key to options[:key_dir]
def create_keypair(options = {})
amazon = connect()
@@ -189,7 +224,7 @@ def run_instance(options = {})
}.merge(options)
# What security group should we run as?
- options[:group_id] = options[:group_name] || get(:group_name)
+ options[:group_id] = (options[:group_name] || get(:group_name) || "").split(',')
# We want to run the new instance using our public/private keypair if
# one is defined for this application or of the user has explicitly passed
@@ -242,7 +277,6 @@ def run_instance(options = {})
instance = amazon.describe_instances(:instance_id => instance_id)
raise "Server Not Running" unless instance.reservationSet.item[0].instancesSet.item[0].instanceState.name == "running"
puts "Instance #{instance_id} is 'running'"
- return instance
rescue
puts "."
sleep(10)
@@ -251,6 +285,35 @@ def run_instance(options = {})
raise "Instance #{instance_id} never moved to state 'running'!"
end
+ #loop waiting to get the public key
+ puts "Checking every 10 seconds detect that we can SSH into this instance for up to 5 minutes"
+ tries = 0
+ begin
+ require 'timeout'
+ begin
+ Timeout::timeout(5) do
+ system("ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -i #{get_key_file} root@#{hostname_from_instance_id(instance_id)} echo success") or raise "SSH Auth Failure"
+ end
+ rescue Timeout::Error
+ raise "SSH timed out..."
+ end
+ puts "SSH is up! Grabbing the public key..."
+ if system "scp -i #{get_key_file} root@#{hostname_from_instance_id(instance_id)}:/mnt/openssh_id.pub #{get_key_file}.pub"
+ puts "Public key saved at #{get_key_file}.pub"
+ else
+ puts "Error grabbing public key"
+ end
+ return instance
+ rescue Exception => e
+ puts e
+ puts "retrying in 10 seconds..."
+ sleep(10)
+ tries += 1
+ retry unless tries == 35
+ puts "We couldn't ever SSH in!"
+ return instance
+ end
+
end
Please sign in to comment.
Something went wrong with that request. Please try again.