class Anjou::EC2
Constants
- DEFAULT_AMI
- DEFAULT_INSTANCE_TYPE
- DEFAULT_SNAPSHOT_NAME
- DEFAULT_USER_DATA
- DEFAULT_ZONE
- KEY_ID
- KEY_PAIR_NAME
- Name
- SECRET_KEY
- SECURITY_GROUP_NAME
- USER_VOL_SIZE
Attributes
api[R]
Public Class Methods
new(access_key_id=KEY_ID, secret_access_key=SECRET_KEY)
click to toggle source
# File lib/anjou/ec2.rb, line 19 def initialize(access_key_id=KEY_ID, secret_access_key=SECRET_KEY) @api = ::AWS::EC2.new( access_key_id: access_key_id, secret_access_key: secret_access_key ) end
Public Instance Methods
attach(username, instance, device=nil)
click to toggle source
# File lib/anjou/ec2.rb, line 107 def attach(username, instance, device=nil) volume = user_volume_for(username) guard_volume_available(volume, username) device ||= next_device_for(instance) volume.attach_to instance, device end
create_instance( username: nil, ami: DEFAULT_AMI, key_name: KEY_PAIR_NAME, zone: DEFAULT_ZONE, instance_type: DEFAULT_INSTANCE_TYPE, user_data: DEFAULT_USER_DATA )
click to toggle source
# File lib/anjou/ec2.rb, line 25 def create_instance( username: nil, ami: DEFAULT_AMI, key_name: KEY_PAIR_NAME, zone: DEFAULT_ZONE, instance_type: DEFAULT_INSTANCE_TYPE, user_data: DEFAULT_USER_DATA ) key_pair = key_pair_for key_name raise "Unable to start instance: no such key pair exists! (key_name: #{key_name})" unless key_pair && key_pair.exists? @api.instances.create( image_id: ami, key_pair: key_pair, availability_zone: zone, instance_type: instance_type, user_data: user_data, security_groups: security_groups ).tap do |instance| if username instance.tags.Name = name_tag_for username instance.tags.owner = username end end end
create_user_volume(username: nil, user_vol_size: USER_VOL_SIZE, zone: DEFAULT_ZONE, snapshot: DEFAULT_SNAPSHOT_NAME)
click to toggle source
# File lib/anjou/ec2.rb, line 64 def create_user_volume(username: nil, user_vol_size: USER_VOL_SIZE, zone: DEFAULT_ZONE, snapshot: DEFAULT_SNAPSHOT_NAME) aws_snapshot = @api.snapshots.tagged('Name').select do |snp| snp.tags.to_a.include? ['Name', snapshot] end.last @api.volumes.create( size: user_vol_size, availability_zone: zone, snapshot: aws_snapshot ).tap do |volume| if username volume.tags.Name = name_tag_for username volume.tags.owner = username end end end
delete_user_volume(username)
click to toggle source
# File lib/anjou/ec2.rb, line 82 def delete_user_volume(username) detach(username).delete end
detach(username)
click to toggle source
# File lib/anjou/ec2.rb, line 114 def detach(username) user_volume_for(username).tap do |volume| volume.attachments.each do |attachment| attachment.delete(force: true) end sleep 1 until volume.status == :available end end
instance_for(username)
click to toggle source
# File lib/anjou/ec2.rb, line 50 def instance_for(username) @api.instances.tagged('owner').select do |instance| instance.tags.to_a.include? ['owner', username] end.select{|i| i.status != :terminated }.last end
instance_status_for(username)
click to toggle source
# File lib/anjou/ec2.rb, line 56 def instance_status_for(username) instance_for(username).status end
key_pair_for(key_name)
click to toggle source
# File lib/anjou/ec2.rb, line 60 def key_pair_for(key_name) @api.key_pairs.select{ |kp| kp.name == key_name }.last end
next_device_for(instance)
click to toggle source
# File lib/anjou/ec2.rb, line 123 def next_device_for(instance) '/dev/sda' + (instance.attachments.keys.size + 1).to_s end
security_groups()
click to toggle source
# File lib/anjou/ec2.rb, line 127 def security_groups @api.security_groups.to_a.select{ |sg| sg.name == 'Anjou' } end
user_volume_for(username)
click to toggle source
# File lib/anjou/ec2.rb, line 86 def user_volume_for(username) @api.volumes.tagged('owner').select do |vol| vol.tags.to_a.include? ['owner', username] end.first end
user_volume_status_for(username)
click to toggle source
# File lib/anjou/ec2.rb, line 92 def user_volume_status_for(username) user_volume_for(username).status end
wait_for_user_volume(username, status: :available, timeout: 15)
click to toggle source
@depricated: this method violates Anjou::EC2's “thin wrapper” contract.
It's a useful method, but it should be implemented elsewhere.
# File lib/anjou/ec2.rb, line 98 def wait_for_user_volume(username, status: :available, timeout: 15) seconds = 0 while user_volume_status_for(username) != status raise "Timeout: After #{timeout} seconds, user volume for #{username} is still not #{status}" if seconds >= timeout seconds += sleep 1 end status end
Private Instance Methods
guard_volume_available(volume, username)
click to toggle source
# File lib/anjou/ec2.rb, line 137 def guard_volume_available(volume, username) volume.status.tap do |status| unless status == :available raise "user volume for \"#{username}\" is not available (status: #{status})" end end end
name_tag_for(username)
click to toggle source
# File lib/anjou/ec2.rb, line 133 def name_tag_for(username) "anjou-#{username || :generic}" end