Skip to content

Instantly share code, notes, and snippets.

@whiteley
Created December 14, 2012 03:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whiteley/4282468 to your computer and use it in GitHub Desktop.
Save whiteley/4282468 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
begin
require 'aws'
rescue LoadError => e
abort "Unable to load library: #{e.message}"
end
require 'Forwardable'
class SandBox < AWS::EC2::Instance
attr_reader :instance, :key, :key_name, :username
extend Forwardable
def_delegators :@instance, :dns_name, :id, :status
SSH_PORT = 22
def initialize(ami_id)
read_config
@ec2 = AWS::EC2.new(:ec2_endpoint => ec2_endpoint)
key_setup
@instance = @ec2.instances.create(:image_id => ami_id, :key_name => @key_name)
end
def ec2_endpoint
ec2_url = ENV['EC2_URL'] || 'https://ec2.us-east-1.amazonaws.com'
ec2_url.split('/').last
end
def key_setup
unless @key = ENV['EC2_KEYPAIR']
abort 'You must export EC2_KEYPAIR'
end
unless @key_name = ENV['EC2_KEYPAIR_NAME']
abort 'You must export EC2_KEYPAIR_NAME'
end
@username = ENV['EC2_USER'] || 'root'
end
def read_config
config_path = File.expand_path(File.join(Dir.home, '.ec2', 'jiffy.yml'))
unless File.exists?(config_path)
abort "#{config_path} must contain :access_key id and :secret_access_key"
end
AWS.config(YAML.load(File.read(config_path)))
end
def tcp_test_ssh
tcp_socket = TCPSocket.new(dns_name, SSH_PORT)
readable = IO.select([tcp_socket], nil, nil, 5)
if readable
yield
true
else
false
end
rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError
sleep 2
false
rescue Errno::EPERM, Errno::ETIMEDOUT
false
ensure
tcp_socket && tcp_socket.close
end
def wait_for_sshd
STDOUT.print(".") until tcp_test_ssh do
sleep @initial_sleep_delay ||= 2
puts("done")
end
end
end
if __FILE__ == $0
if ARGV.length != 1
abort "Usage: #{__FILE__} ami-id"
end
ami_id = ARGV[0]
unless ami_id =~ /^ami-[0-9a-f]{8}$/
abort "Malformed AMI id"
end
i = SandBox.new(ami_id)
puts "Instance [#{i.id}] created"
print '... waiting for boot ...'
until i.status == :running
print('.')
sleep @initial_sleep_delay ||= 2
end
puts("done")
print '... waiting for sshd ...'
i.wait_for_sshd
exec('ssh', '-oForwardAgent=yes', '-oUserKnownHostsFile=/dev/null', '-oStrictHostKeyChecking=no', '-l', i.username, '-i', i.key, i.dns_name)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment