class InstantEC2

Attributes

async[R]
images[R]

Public Class Methods

new(credentials: [], region: 'us-east-1', async: true) click to toggle source
# File lib/instant_ec2.rb, line 46
def initialize(credentials: [], region: 'us-east-1', async: true)
  
  @async = async

  @ec2 = Aws::EC2::Client.new(region: region, 
                             credentials: Aws::Credentials.new(*credentials))

  r = @ec2.describe_instances.reservations
  
  ids = @ec2.describe_instances[:reservations].inject({}) do |r, item| 
    x = item.instances[0]
    r.merge(x.image_id => x.instance_id)
  end

  rows = @ec2.describe_images(image_ids: ids.keys)[:images].\
                                               map{|x| [x.name, x.image_id] }

  @images = rows.inject([]) do |r, x|

    name, image_id = x
    
    r << EC2Instance.new({image_name: name, \
                                       instance_id: ids[image_id]}, self)
    
  end

  @hooks = {
    pending: ->(){ 
      puts "%s: the instance is now pending" % [Time.now]
    },
    running: ->(ip){ 
      puts "%s: the instance is now accessible from %s" % [Time.now, ip]
    },
    stopping: ->(){ puts "%s: the instance is now stopping" % Time.now}
  }

end

Public Instance Methods

find_image(s) click to toggle source
# File lib/instant_ec2.rb, line 84
def find_image(s)
  @images.find {|x| x[:image_name][/#{s}/i]}
end
find_pending() click to toggle source
# File lib/instant_ec2.rb, line 88
def find_pending()

  r = @ec2.describe_instances.reservations.detect do |x|
    x.instances[0].state.name == 'pending'
  end

end
find_running() click to toggle source
# File lib/instant_ec2.rb, line 96
def find_running()

  r = @ec2.describe_instances.reservations.detect do |x|
    x.instances[0].state.name == 'running'
  end

end
ip() click to toggle source
# File lib/instant_ec2.rb, line 104
def ip()
  r = self.find_running
  r.instances[0].public_ip_address if r
end
on_pending(&blk) click to toggle source
# File lib/instant_ec2.rb, line 109
def on_pending(&blk)
  @hooks[:pending]= blk
end
on_running(&blk) click to toggle source
# File lib/instant_ec2.rb, line 113
def on_running(&blk)
  @hooks[:running] = blk
end
on_stopped(&blk) click to toggle source
# File lib/instant_ec2.rb, line 117
def on_stopped(&blk)
  @hooks[:stopped] = blk
end
running?() click to toggle source
# File lib/instant_ec2.rb, line 121
def running?
  self.ip ? true : false
end
start(s, duration: nil) click to toggle source

Launch an EC2 instance. Duration (optional) specified in minutes

# File lib/instant_ec2.rb, line 127
def start(s, duration: nil)
  
  found = self.find_image(s)
  return unless found
  
  found.start duration: duration
  
end
start_instance(id) click to toggle source
# File lib/instant_ec2.rb, line 136
def start_instance(id)
  @ec2.start_instances instance_ids: [id]
  @async ? Thread.new { trigger_on_start() } : trigger_on_start()
end
stop() click to toggle source
# File lib/instant_ec2.rb, line 141
def stop()

  r = self.find_running()

  if r then
    
    puts 'stopping ...'
    
    self.stop_instance r.instances[0].instance_id      
    
  else
    puts 'no instances to stop'
  end
end
stop_instance(id) click to toggle source
# File lib/instant_ec2.rb, line 156
def stop_instance(id)
  @ec2.stop_instances instance_ids: [id]
  @async ? Thread.new { trigger_on_stopping() } : trigger_on_stopping()
end
stopped?() click to toggle source
# File lib/instant_ec2.rb, line 161
def stopped?()
  self.ip.nil?
end

Private Instance Methods

trigger_on_running() click to toggle source
# File lib/instant_ec2.rb, line 184
def trigger_on_running()
  
  # timeout after 30 seconds
  t1 = Time.now
  sleep 1; ip = self.ip until ip or Time.now > t1 + 30
  
  if ip then 
    @hooks[:running].call(ip)
  else
    puts 'on_running timedout'
  end
  
end
trigger_on_start() click to toggle source
# File lib/instant_ec2.rb, line 168
def trigger_on_start()
  
  # timeout after 60 seconds
  t1 = Time.now
  sleep 10
  sleep 2; pending = self.find_pending() until pending or Time.now > t1 + 60
  
  if pending then
    @hooks[:pending].call()
    trigger_on_running()
  else
    puts 'on_running timedout'
  end
  
end
trigger_on_stopping() click to toggle source
# File lib/instant_ec2.rb, line 198
def trigger_on_stopping()
  
  # timeout after 30 seconds
  t1 = Time.now
  sleep 7
  sleep 2; ip = self.ip until ip.nil? or Time.now > t1 + 30
  
  if ip.nil? then 
    @hooks[:stopping].call()
  else
    puts 'on_stopping timedout'
  end
  
end