lib/kitchen/driver/ec2.rb in kitchen-ec2-3.0.1 vs lib/kitchen/driver/ec2.rb in kitchen-ec2-3.1.0
- old
+ new
@@ -72,10 +72,11 @@
default_config :private_ip_address, nil
default_config :iam_profile_name, nil
default_config :spot_price, nil
default_config :block_duration_minutes, nil
default_config :retryable_tries, 60
+ default_config :spot_wait, 60
default_config :retryable_sleep, 5
default_config :aws_access_key_id, nil
default_config :aws_secret_access_key, nil
default_config :aws_session_token, nil
default_config :aws_ssh_key_id, ENV["AWS_SSH_KEY_ID"]
@@ -227,22 +228,19 @@
config[:aws_ssh_key_id] = nil
end
if config[:spot_price]
# Spot instance when a price is set
- server = with_request_limit_backoff(state) { submit_spot(state) }
+ server = with_request_limit_backoff(state) { submit_spots(state) }
else
# On-demand instance
server = with_request_limit_backoff(state) { submit_server }
end
info("Instance <#{server.id}> requested.")
with_request_limit_backoff(state) do
- server.wait_until_exists do |w|
- w.before_attempt do |attempts|
- info("Polling AWS for existence, attempt #{attempts}...")
- end
- end
+ logging_proc = ->(attempts) { info("Polling AWS for existence, attempt #{attempts}...") }
+ server.wait_until_exists(before_attempt: logging_proc)
end
# See https://github.com/aws/aws-sdk-ruby/issues/859
# Tagging can fail with a NotFound error even though we waited until the server exists
# Waiting can also fail, so we have to also retry on that. If it means we re-tag the
@@ -405,11 +403,11 @@
config[:ssl_verify_peer]
)
end
def instance_generator
- @instance_generator ||= Aws::InstanceGenerator.new(config, ec2, instance.logger)
+ @instance_generator = Aws::InstanceGenerator.new(config, ec2, instance.logger)
end
# Fog AWS helper for creating the instance
def submit_server
instance_data = instance_generator.ec2_instance_data
@@ -420,10 +418,57 @@
instance_data[:min_count] = 1
instance_data[:max_count] = 1
ec2.create_instance(instance_data)
end
+ def config
+ return super unless @config
+ @config
+ end
+
+ # Take one config and expand to multiple configs
+ def expand_config(conf, key)
+ configs = []
+
+ if conf[key] && conf[key].kind_of?(Array)
+ values = conf[key]
+ values.each do |value|
+ new_config = conf.clone
+ new_config[key] = value
+ configs.push new_config
+ end
+ else
+ configs.push conf
+ end
+
+ configs
+ end
+
+ def submit_spots(state)
+ configs = [config]
+ expanded = []
+ keys = [:instance_type, :subnet_id]
+
+ keys.each do |key|
+ configs.each do |conf|
+ expanded.push expand_config(conf, key)
+ end
+ configs = expanded.flatten
+ expanded = []
+ end
+
+ configs.each do |conf|
+ begin
+ @config = conf
+ return submit_spot(state)
+ rescue
+ end
+ end
+
+ raise "Could not create a spot"
+ end
+
def submit_spot(state)
debug("Creating EC2 Spot Instance..")
spot_request_id = create_spot_request
# deleting the instance cancels the request, but deleting the request
@@ -431,25 +476,31 @@
state[:spot_request_id] = spot_request_id
ec2.client.wait_until(
:spot_instance_request_fulfilled,
spot_instance_request_ids: [spot_request_id]
) do |w|
- w.max_attempts = config[:retryable_tries]
+ w.max_attempts = config[:spot_wait] / config[:retryable_sleep]
w.delay = config[:retryable_sleep]
w.before_attempt do |attempts|
c = attempts * config[:retryable_sleep]
- t = config[:retryable_tries] * config[:retryable_sleep]
+ t = config[:spot_wait]
info "Waited #{c}/#{t}s for spot request <#{spot_request_id}> to become fulfilled."
end
end
ec2.get_instance_from_spot_request(spot_request_id)
end
def create_spot_request
- request_duration = config[:retryable_tries] * config[:retryable_sleep]
+ request_duration = config[:spot_wait]
+ config_spot_price = config[:spot_price].to_s
+ if ["ondemand", "on-demand"].include?(config_spot_price)
+ spot_price = ""
+ else
+ spot_price = config_spot_price
+ end
request_data = {
- spot_price: config[:spot_price].to_s,
+ spot_price: spot_price,
launch_specification: instance_generator.ec2_instance_data,
valid_until: Time.now + request_duration,
}
if config[:block_duration_minutes]
request_data[:block_duration_minutes] = config[:block_duration_minutes]
@@ -591,9 +642,10 @@
{
"dns" => "public_dns_name",
"public" => "public_ip_address",
"private" => "private_ip_address",
"private_dns" => "private_dns_name",
+ "id" => "id",
}.freeze
#
# Lookup hostname of provided server. If interface_type is provided use
# that interface to lookup hostname. Otherwise, try ordered list of