1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

add spot instance request models

This commit is contained in:
Edward Middleton 2011-07-02 13:30:32 +09:00
parent f7e4797834
commit f40538fc69
4 changed files with 254 additions and 0 deletions

View file

@ -24,6 +24,8 @@ module Fog
collection :tags
model :volume
collection :volumes
model :spot_request
collection :spot_requests
request_path 'fog/compute/requests/aws'
request :allocate_address

View file

@ -0,0 +1,83 @@
require 'fog/core/model'
module Fog
module Compute
class AWS
class SpotRequest < Fog::Model
identity :id, :aliases => 'spotInstanceRequestId'
attribute :price, :aliases => 'spotPrice'
attribute :request_type, :aliases => 'type'
attribute :created_at, :aliases => 'createTime'
attribute :instance_count, :aliases => 'instanceCount'
attribute :state
# TODO: not sure how to handle
#attribute :fault
attribute :valid_from, :aliases => 'validFrom'
attribute :valid_until, :aliases => 'validUntil'
attribute :launch_group, :aliases => 'launchGroup'
attribute :availability_zone_group, :aliases => 'availabilityZoneGroup'
attribute :product_description, :aliases => 'productDescription'
attribute :groups, :aliases => 'LaunchSpecification.SecurityGroup'
attribute :key_name, :aliases => 'LaunchSpecification.KeyName'
attribute :availability_zone, :aliases => 'launchedAvailabilityZone'
attribute :flavor_id, :aliases => 'LaunchSpecification.InstanceType'
attribute :image_id, :aliases => 'LaunchSpecification.ImageId'
attribute :monitoring, :aliases => 'LaunchSpecification.Monitoring'
attr_writer :username
def initialize(attributes={})
self.groups ||= ["default"]
self.flavor_id ||= 't1.micro'
self.image_id ||= begin
self.username = 'ubuntu'
case attributes[:connection].instance_variable_get(:@region) # Ubuntu 10.04 LTS 64bit (EBS)
when 'ap-northeast-1'
'ami-5e0fa45f'
when 'ap-southeast-1'
'ami-f092eca2'
when 'eu-west-1'
'ami-3d1f2b49'
when 'us-east-1'
'ami-3202f25b'
when 'us-west-1'
'ami-f5bfefb0'
end
end
self.instance_count ||= 1
super
end
# def destroy
# requires :name
# connection.delete_spot_request(name)
# true
# end
def save
requires :image_id, :flavor_id, :price
options = {
'InstanceCount' => instance_count,
'LaunchSpecification.KeyName' => key_name,
'LaunchSpecification.Placement.AvailabilityZone' => availability_zone,
'LaunchSpecification.SecurityGroup' => groups,
'Type' => request_type }
connection.request_spot_instances(image_id, flavor_id, price, options)
end
def ready?
state == 'active'
end
end
end
end
end

View file

@ -0,0 +1,47 @@
require 'fog/core/collection'
require 'fog/compute/models/aws/spot_request'
module Fog
module Compute
class AWS
class SpotRequests < Fog::Collection
attribute :filters
model Fog::Compute::AWS::SpotRequest
def initialize(attributes)
self.filters ||= {}
super
end
def all(filters = self.filters)
unless filters.is_a?(Hash)
Formatador.display_line("[yellow][WARN] all with #{filters.class} param is deprecated, use all('spot-instance-request-id' => []) instead[/] [light_black](#{caller.first})[/]")
filters = {'spot-instance-request-id' => [*filters]}
end
self.filters = filters
data = connection.describe_spot_instance_requests(filters).body
load(
data['spotInstanceRequestSet'].map do |spot_instance_request|
spot_instance_request['launchSpecification'].each do |name,value|
spot_instance_request['LaunchSpecification.' + name[0,1].upcase + name[1..-1]] = value
end
spot_instance_request.merge(:groups => spot_instance_request['LaunchSpecification.GroupSet'])
spot_instance_request
end.flatten
)
end
def get(spot_request_id)
if spot_request_id
self.class.new(:connection => connection).all('spot-instance-request-id' => spot_request_id).first
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,122 @@
module Fog
module AWS
class Compute
class Real
require 'fog/compute/parsers/aws/request_spot_instance'
# Creates a Spot Instance request
#
# ==== Parameters
# * image_id<~String> - Id of machine image to load on instances
# * max_price<~String> - The maximum hourly price
# * max_count<~Integer> -The maximium number of instances to launch
# * options<~Hash>:
# * Type<~String> - request type ['one-time'|'persistent']
# * ValidFrom<>
# * ValidUntil<>
# * LaunchGroup<>
# * AvailabilityZoneGroup<>
# * LaunchSpecification<~Hash>
# * 'Placement.AvailabilityZone'<~String> - Placement constraint for instances
# * 'BlockDeviceMapping'<~Array>: array of hashes
# * 'DeviceName'<~String> - where the volume will be exposed to instance
# * 'VirtualName'<~String> - volume virtual device name
# * 'Ebs.SnapshotId'<~String> - id of snapshot to boot volume from
# * 'Ebs.VolumeSize'<~String> - size of volume in GiBs required unless snapshot is specified
# * 'Ebs.NoDevice'<~String> - specifies that no device should be mappped
# * 'Ebs.DeleteOnTermination'<~String> - specifies whether or not to delete the volume on instance termination
# * 'ClientToken'<~String> - unique case-sensitive token for ensuring idempotency
# * 'SecurityGroup'<~Array> or <~String> - Name of security group(s) for instances (you must omit this parameter if using Virtual Private Clouds)
# * 'InstanceInitiatedShutdownBehaviour'<~String> - specifies whether volumes are stopped or terminated when instance is shutdown, in [stop, terminate]
# * 'InstanceType'<~String> - Type of instance to boot. Valid options
# in ['m1.small', 'm1.large', 'm1.xlarge', 'c1.medium', 'c1.xlarge', 'm2.xlarge', 'm2.2xlarge', 'm2.4xlarge', 't1.micro']
# default is 'm1.small'
# * 'KernelId'<~String> - Id of kernel with which to launch
# * 'KeyName'<~String> - Name of a keypair to add to booting instances
# * 'Monitoring.Enabled'<~Boolean> - Enables monitoring, defaults to
# disabled
# * 'RamdiskId'<~String> - Id of ramdisk with which to launch
# * 'UserData'<~String> - Additional data to provide to booting instances
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'spotInstanceRequestSet'<~Array>: array of hashes
# * 'item'<~Hash>:
# * 'spotInstanceRequestId'<~String> -
# * 'spotPrice
# * 'amiLaunchIndex'<~Integer> - reference to instance in launch group
# * 'architecture'<~String> - architecture of image in [i386, x86_64]
# * 'blockDeviceMapping'<~Array>
# * 'attachTime'<~Time> - time of volume attachment
# * 'deleteOnTermination'<~Boolean> - whether or not to delete volume on termination
# * 'deviceName'<~String> - specifies how volume is exposed to instance
# * 'status'<~String> - status of attached volume
# * 'volumeId'<~String> - Id of attached volume
# * 'dnsName'<~String> - public dns name, blank until instance is running
# * 'imageId'<~String> - image id of ami used to launch instance
# * 'instanceId'<~String> - id of the instance
# * 'instanceState'<~Hash>:
# * 'code'<~Integer> - current status code
# * 'name'<~String> - current status name
# * 'instanceType'<~String> - type of instance
# * 'ipAddress'<~String> - public ip address assigned to instance
# * 'kernelId'<~String> - Id of kernel used to launch instance
# * 'keyName'<~String> - name of key used launch instances or blank
# * 'launchTime'<~Time> - time instance was launched
# * 'monitoring'<~Hash>:
# * 'state'<~Boolean - state of monitoring
# * 'placement'<~Hash>:
# * 'availabilityZone'<~String> - Availability zone of the instance
# * 'privateDnsName'<~String> - private dns name, blank until instance is running
# * 'privateIpAddress'<~String> - private ip address assigned to instance
# * 'productCodes'<~Array> - Product codes for the instance
# * 'ramdiskId'<~String> - Id of ramdisk used to launch instance
# * 'reason'<~String> - reason for most recent state transition, or blank
# * 'rootDeviceName'<~String> - specifies how the root device is exposed to the instance
# * 'rootDeviceType'<~String> - root device type used by AMI in [ebs, instance-store]
def request_spot_instance(image_id, max_price, max_count, options = {})
launch_specification = options.delete('LaunchSpecification')
if block_device_mapping = launch_specification.delete('BlockDeviceMapping')
block_device_mapping.each_with_index do |mapping, index|
for key, value in mapping
launch_specification.merge!({ format("BlockDeviceMapping.%d.#{key}", index) => value })
end
end
end
if security_groups = launch_specification.delete('SecurityGroup')
launch_specification.merge!(AWS.indexed_param('SecurityGroup', [*security_groups]))
end
if launch_specification['UserData']
launch_specification['UserData'] = Base64.encode64(launch_specification['UserData'])
end
idempotent = !(launch_specification['ClientToken'].nil? || launch_specification['ClientToken'].empty?)
request({
'Action' => 'RequestSpotInstances',
'SpotPrice' => max_price,
'InstanceCount' => max_count,
'MinCount' => min_count,
'LaunchSpecification.ImageId' => image_id,
:idempotent => idempotent,
:parser => Fog::Parsers::AWS::Compute::RunInstances.new
}.merge!('LaunchSpecification' => launch_specification))
end
end
class Mock
def request_spot_instance(image_id, max_price, max_count, options = {})
response = Excon::Response.new
response.status = 200
group_set = [ (options['
end
end
end
end
end