diff --git a/README.md b/README.md index 70920841..fe1c274c 100644 --- a/README.md +++ b/README.md @@ -284,7 +284,7 @@ The EC2 IAM profile name to use. The default is `nil`. -### `price` +### `spot_price` The price you bid in order to submit a spot request. An additional step will be required during the spot request process submission. If no price is set, it will use an on-demand instance. diff --git a/lib/kitchen/driver/ec2.rb b/lib/kitchen/driver/ec2.rb index 410534f2..0501a1b7 100644 --- a/lib/kitchen/driver/ec2.rb +++ b/lib/kitchen/driver/ec2.rb @@ -62,7 +62,7 @@ class Ec2 < Kitchen::Driver::Base # rubocop:disable Metrics/ClassLength end default_config :private_ip_address, nil default_config :iam_profile_name, nil - default_config :price, nil + default_config :spot_price, nil default_config :block_duration_minutes, nil default_config :retryable_tries, 60 default_config :retryable_sleep, 5 @@ -162,7 +162,7 @@ def create(state) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength are responsible for your incurred costs. END - if config[:price] + if config[:spot_price] # Spot instance when a price is set server = submit_spot(state) else @@ -321,13 +321,8 @@ def submit_server def submit_spot(state) # rubocop:disable Metrics/AbcSize debug("Creating EC2 Spot Instance..") - request_data = {} - request_data[:spot_price] = config[:price].to_s - request_data[:launch_specification] = instance_generator.ec2_instance_data - request_data[:block_duration_minutes] = config[:block_duration_minutes] if config[:block_duration_minutes] - response = ec2.client.request_spot_instances(request_data) - spot_request_id = response[:spot_instance_requests][0][:spot_instance_request_id] + spot_request_id = create_spot_request # deleting the instance cancels the request, but deleting the request # does not affect the instance state[:spot_request_id] = spot_request_id @@ -346,6 +341,19 @@ def submit_spot(state) # rubocop:disable Metrics/AbcSize ec2.get_instance_from_spot_request(spot_request_id) end + def create_spot_request + request_data = { + :spot_price => config[:spot_price].to_s, + :launch_specification => instance_generator.ec2_instance_data + } + if config[:block_duration_minutes] + request_data[:block_duration_minutes] = config[:block_duration_minutes] + end + + response = ec2.client.request_spot_instances(request_data) + response[:spot_instance_requests][0][:spot_instance_request_id] + end + def tag_server(server) tags = [] config[:tags].each do |k, v| diff --git a/spec/kitchen/driver/ec2_spec.rb b/spec/kitchen/driver/ec2_spec.rb index 999a4d5a..6bc5b6d1 100644 --- a/spec/kitchen/driver/ec2_spec.rb +++ b/spec/kitchen/driver/ec2_spec.rb @@ -25,7 +25,13 @@ let(:logged_output) { StringIO.new } let(:logger) { Logger.new(logged_output) } - let(:config) { { :aws_ssh_key_id => "key", :image_id => "ami-1234567", :block_duration_minutes => 60 } } + let(:config) do + { + :aws_ssh_key_id => "key", + :image_id => "ami-1234567", + :block_duration_minutes => 60 + } + end let(:platform) { Kitchen::Platform.new(:name => "fooos-99") } let(:transport) { Kitchen::Transport::Dummy.new } let(:generator) { instance_double(Kitchen::Driver::Aws::InstanceGenerator) } @@ -361,7 +367,7 @@ context "config is for a spot instance" do before do - config[:price] = 1 + config[:spot_price] = 1 expect(driver).to receive(:submit_spot).with(state).and_return(server) end