kitchen-ec2 3.2.0 → 3.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kitchen/driver/aws/client.rb +10 -0
- data/lib/kitchen/driver/aws/instance_generator.rb +46 -19
- data/lib/kitchen/driver/aws/standard_platform/amazon.rb +3 -1
- data/lib/kitchen/driver/aws/standard_platform/amazon2.rb +3 -1
- data/lib/kitchen/driver/aws/standard_platform/centos.rb +3 -1
- data/lib/kitchen/driver/aws/standard_platform/debian.rb +5 -2
- data/lib/kitchen/driver/aws/standard_platform/fedora.rb +3 -1
- data/lib/kitchen/driver/aws/standard_platform/freebsd.rb +3 -1
- data/lib/kitchen/driver/aws/standard_platform/rhel.rb +3 -1
- data/lib/kitchen/driver/aws/standard_platform/ubuntu.rb +3 -1
- data/lib/kitchen/driver/aws/standard_platform/windows.rb +3 -1
- data/lib/kitchen/driver/ec2.rb +45 -102
- data/lib/kitchen/driver/ec2_version.rb +2 -2
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d6429e51c08d43c0e1084b9acc55b76feacae05bbe42b7cf3a1e35e0de70f87
|
4
|
+
data.tar.gz: 9f2a0adbe2866ad6a267ab8adc14d24a890b22b71b0abe272808a2a52def3933
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa308480b37d109ec173851aefe0098523d2a59c06481e88004bf76ccb8d87dfbd865300d2383157af13b38af47588ec2d1adf0541734f7279669a8dbcb0b673
|
7
|
+
data.tar.gz: 48f6f1a3dc22caf5d04079ef1579c19850e7e72558708e633537adb752969c3aac1b79702804864fac3fad9140e8d9053347c3ecde47e578e0545366d0b0b619
|
@@ -49,14 +49,24 @@ module Kitchen
|
|
49
49
|
::Aws.config.update(retry_limit: retry_limit) unless retry_limit.nil?
|
50
50
|
end
|
51
51
|
|
52
|
+
# create a new AWS EC2 instance
|
53
|
+
# @param options [Hash] has of instance options
|
54
|
+
# @see https://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Resource.html#create_instances-instance_method
|
55
|
+
# @return [Aws::EC2::Instance]
|
52
56
|
def create_instance(options)
|
53
57
|
resource.create_instances(options).first
|
54
58
|
end
|
55
59
|
|
60
|
+
# get an instance object given an id
|
61
|
+
# @param id [String] aws instance id
|
62
|
+
# @return [Aws::EC2::Instance]
|
56
63
|
def get_instance(id)
|
57
64
|
resource.instance(id)
|
58
65
|
end
|
59
66
|
|
67
|
+
# get an instance object given a spot request ID
|
68
|
+
# @param request_id [String] aws spot instance id
|
69
|
+
# @return [Aws::EC2::Instance]
|
60
70
|
def get_instance_from_spot_request(request_id)
|
61
71
|
resource.instances(
|
62
72
|
filters: [{
|
@@ -39,29 +39,34 @@ module Kitchen
|
|
39
39
|
@logger = logger
|
40
40
|
end
|
41
41
|
|
42
|
-
# Transform the provided config into the hash
|
42
|
+
# Transform the provided kitchen config into the hash we'll use to create the aws instance
|
43
43
|
# can be passed in null, others need to be ommitted if they are null
|
44
|
+
# Some fields can be passed in null, others need to be ommitted if they are null
|
45
|
+
# @return [Hash]
|
44
46
|
def ec2_instance_data # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
45
47
|
# Support for looking up security group id and subnet id using tags.
|
46
|
-
|
48
|
+
vpc_id = nil
|
49
|
+
client = ::Aws::EC2::Client.new(region: config[:region])
|
47
50
|
if config[:subnet_id].nil? && config[:subnet_filter]
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
{
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
if
|
59
|
-
|
60
|
-
|
61
|
-
|
51
|
+
subnets = client.describe_subnets(
|
52
|
+
filters: [
|
53
|
+
{
|
54
|
+
name: "tag:#{config[:subnet_filter][:tag]}",
|
55
|
+
values: [config[:subnet_filter][:value]],
|
56
|
+
},
|
57
|
+
]
|
58
|
+
).subnets
|
59
|
+
raise "The subnet tagged '#{config[:subnet_filter][:tag]}:#{config[:subnet_filter][:value]}' does not exist!" unless subnets.any?
|
60
|
+
|
61
|
+
# => Select the least-populated subnet if we have multiple matches
|
62
|
+
subnet = subnets.sort_by { |s| s[:available_ip_address_count] }.last
|
63
|
+
vpc_id = subnet.vpc_id
|
64
|
+
config[:subnet_id] = subnet.subnet_id
|
62
65
|
end
|
63
66
|
|
64
67
|
if config[:security_group_ids].nil? && config[:security_group_filter]
|
68
|
+
# => Grab the VPC in the case a Subnet ID rather than Filter was set
|
69
|
+
vpc_id ||= client.describe_subnets(subnet_ids: [config[:subnet_id]]).subnets[0].vpc_id
|
65
70
|
security_groups = []
|
66
71
|
filters = [config[:security_group_filter]].flatten
|
67
72
|
filters.each do |sg_filter|
|
@@ -72,6 +77,10 @@ module Kitchen
|
|
72
77
|
name: "group-name",
|
73
78
|
values: [sg_filter[:name]],
|
74
79
|
},
|
80
|
+
{
|
81
|
+
name: "vpc-id",
|
82
|
+
values: [vpc_id],
|
83
|
+
},
|
75
84
|
]
|
76
85
|
end
|
77
86
|
|
@@ -81,13 +90,17 @@ module Kitchen
|
|
81
90
|
name: "tag:#{sg_filter[:tag]}",
|
82
91
|
values: [sg_filter[:value]],
|
83
92
|
},
|
93
|
+
{
|
94
|
+
name: "vpc-id",
|
95
|
+
values: [vpc_id],
|
96
|
+
},
|
84
97
|
]
|
85
98
|
end
|
86
99
|
|
87
|
-
security_group =
|
100
|
+
security_group = client.describe_security_groups(r).security_groups
|
88
101
|
|
89
|
-
if security_group
|
90
|
-
security_groups.push(
|
102
|
+
if security_group.any?
|
103
|
+
security_group.each { |sg| security_groups.push(sg.group_id) }
|
91
104
|
else
|
92
105
|
raise "A Security Group matching the following filter could not be found:\n#{sg_filter}"
|
93
106
|
end
|
@@ -102,8 +115,22 @@ module Kitchen
|
|
102
115
|
key_name: config[:aws_ssh_key_id],
|
103
116
|
subnet_id: config[:subnet_id],
|
104
117
|
private_ip_address: config[:private_ip_address],
|
118
|
+
min_count: 1,
|
119
|
+
max_count: 1,
|
105
120
|
}
|
106
121
|
|
122
|
+
if config[:tags] && !config[:tags].empty?
|
123
|
+
tags = config[:tags].map do |k, v|
|
124
|
+
# we convert the value to a string because
|
125
|
+
# nils should be passed as an empty String
|
126
|
+
# and Integers need to be represented as Strings
|
127
|
+
{ key: k, value: v.to_s }
|
128
|
+
end
|
129
|
+
instance_tag_spec = { resource_type: "instance", tags: tags }
|
130
|
+
volume_tag_spec = { resource_type: "volume", tags: tags }
|
131
|
+
i[:tag_specifications] = [instance_tag_spec, volume_tag_spec]
|
132
|
+
end
|
133
|
+
|
107
134
|
availability_zone = config[:availability_zone]
|
108
135
|
if availability_zone
|
109
136
|
if availability_zone =~ /^[a-z]$/i
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
16
|
+
require_relative "../standard_platform"
|
17
17
|
|
18
18
|
module Kitchen
|
19
19
|
module Driver
|
@@ -23,6 +23,8 @@ module Kitchen
|
|
23
23
|
class Amazon < StandardPlatform
|
24
24
|
StandardPlatform.platforms["amazon"] = self
|
25
25
|
|
26
|
+
# default username for this platform's ami
|
27
|
+
# @return [String]
|
26
28
|
def username
|
27
29
|
"ec2-user"
|
28
30
|
end
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
16
|
+
require_relative "../standard_platform"
|
17
17
|
|
18
18
|
module Kitchen
|
19
19
|
module Driver
|
@@ -23,6 +23,8 @@ module Kitchen
|
|
23
23
|
class Amazon2 < StandardPlatform
|
24
24
|
StandardPlatform.platforms["amazon2"] = self
|
25
25
|
|
26
|
+
# default username for this platform's ami
|
27
|
+
# @return [String]
|
26
28
|
def username
|
27
29
|
"ec2-user"
|
28
30
|
end
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
16
|
+
require_relative "../standard_platform"
|
17
17
|
|
18
18
|
module Kitchen
|
19
19
|
module Driver
|
@@ -23,6 +23,8 @@ module Kitchen
|
|
23
23
|
class Centos < StandardPlatform
|
24
24
|
StandardPlatform.platforms["centos"] = self
|
25
25
|
|
26
|
+
# default username for this platform's ami
|
27
|
+
# @return [String]
|
26
28
|
def username
|
27
29
|
# Centos 6.x images use root as the username (but the "centos 6"
|
28
30
|
# updateable image uses "centos")
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
16
|
+
require_relative "../standard_platform"
|
17
17
|
|
18
18
|
module Kitchen
|
19
19
|
module Driver
|
@@ -26,14 +26,17 @@ module Kitchen
|
|
26
26
|
# 10/11 are listed last since we default to the first item in the hash
|
27
27
|
# and 10/11 are not released yet. When they're released move them up
|
28
28
|
DEBIAN_CODENAMES = {
|
29
|
+
10 => "buster",
|
29
30
|
9 => "stretch",
|
30
31
|
8 => "jessie",
|
31
32
|
7 => "wheezy",
|
32
33
|
6 => "squeeze",
|
33
34
|
11 => "bullseye",
|
34
|
-
|
35
|
+
12 => "bookworm",
|
35
36
|
}.freeze
|
36
37
|
|
38
|
+
# default username for this platform's ami
|
39
|
+
# @return [String]
|
37
40
|
def username
|
38
41
|
"admin"
|
39
42
|
end
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
16
|
+
require_relative "../standard_platform"
|
17
17
|
|
18
18
|
module Kitchen
|
19
19
|
module Driver
|
@@ -23,6 +23,8 @@ module Kitchen
|
|
23
23
|
class Fedora < StandardPlatform
|
24
24
|
StandardPlatform.platforms["fedora"] = self
|
25
25
|
|
26
|
+
# default username for this platform's ami
|
27
|
+
# @return [String]
|
26
28
|
def username
|
27
29
|
"fedora"
|
28
30
|
end
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
16
|
+
require_relative "../standard_platform"
|
17
17
|
|
18
18
|
module Kitchen
|
19
19
|
module Driver
|
@@ -23,6 +23,8 @@ module Kitchen
|
|
23
23
|
class Freebsd < StandardPlatform
|
24
24
|
StandardPlatform.platforms["freebsd"] = self
|
25
25
|
|
26
|
+
# default username for this platform's ami
|
27
|
+
# @return [String]
|
26
28
|
def username
|
27
29
|
"ec2-user"
|
28
30
|
end
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
16
|
+
require_relative "../standard_platform"
|
17
17
|
|
18
18
|
module Kitchen
|
19
19
|
module Driver
|
@@ -29,6 +29,8 @@ module Kitchen
|
|
29
29
|
super(driver, "rhel", version, architecture)
|
30
30
|
end
|
31
31
|
|
32
|
+
# default username for this platform's ami
|
33
|
+
# @return [String]
|
32
34
|
def username
|
33
35
|
(version && version.to_f < 6.4) ? "root" : "ec2-user"
|
34
36
|
end
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
16
|
+
require_relative "../standard_platform"
|
17
17
|
|
18
18
|
module Kitchen
|
19
19
|
module Driver
|
@@ -23,6 +23,8 @@ module Kitchen
|
|
23
23
|
class Ubuntu < StandardPlatform
|
24
24
|
StandardPlatform.platforms["ubuntu"] = self
|
25
25
|
|
26
|
+
# default username for this platform's ami
|
27
|
+
# @return [String]
|
26
28
|
def username
|
27
29
|
"ubuntu"
|
28
30
|
end
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
16
|
+
require_relative "../standard_platform"
|
17
17
|
|
18
18
|
module Kitchen
|
19
19
|
module Driver
|
@@ -23,6 +23,8 @@ module Kitchen
|
|
23
23
|
class Windows < StandardPlatform
|
24
24
|
StandardPlatform.platforms["windows"] = self
|
25
25
|
|
26
|
+
# default username for this platform's ami
|
27
|
+
# @return [String]
|
26
28
|
def username
|
27
29
|
"administrator"
|
28
30
|
end
|
data/lib/kitchen/driver/ec2.rb
CHANGED
@@ -227,7 +227,7 @@ module Kitchen
|
|
227
227
|
|
228
228
|
if config[:spot_price]
|
229
229
|
# Spot instance when a price is set
|
230
|
-
server = with_request_limit_backoff(state) { submit_spots
|
230
|
+
server = with_request_limit_backoff(state) { submit_spots }
|
231
231
|
else
|
232
232
|
# On-demand instance
|
233
233
|
server = with_request_limit_backoff(state) { submit_server }
|
@@ -238,32 +238,16 @@ module Kitchen
|
|
238
238
|
server.wait_until_exists(before_attempt: logging_proc)
|
239
239
|
end
|
240
240
|
|
241
|
+
state[:server_id] = server.id
|
242
|
+
info("EC2 instance <#{state[:server_id]}> created.")
|
243
|
+
|
241
244
|
# See https://github.com/aws/aws-sdk-ruby/issues/859
|
242
|
-
#
|
243
|
-
# Waiting can also fail, so we have to also retry on that. If it means we re-tag the
|
244
|
-
# instance, so be it.
|
245
|
-
# Tagging an instance is possible before volumes are attached. Tagging the volumes after
|
246
|
-
# instance creation is consistent.
|
245
|
+
# Waiting can fail, so we have to retry on that.
|
247
246
|
Retryable.retryable(
|
248
247
|
tries: 10,
|
249
248
|
sleep: lambda { |n| [2**n, 30].min },
|
250
249
|
on: ::Aws::EC2::Errors::InvalidInstanceIDNotFound
|
251
250
|
) do |r, _|
|
252
|
-
info("Attempting to tag the instance, #{r} retries")
|
253
|
-
tag_server(server)
|
254
|
-
|
255
|
-
# Get information about the AMI (image) used to create the image.
|
256
|
-
image_data = ec2.client.describe_images({ image_ids: [server.image_id] })[0][0]
|
257
|
-
|
258
|
-
state[:server_id] = server.id
|
259
|
-
info("EC2 instance <#{state[:server_id]}> created.")
|
260
|
-
|
261
|
-
# instance-store backed images do not have attached volumes, so only
|
262
|
-
# wait for the volumes to be ready if the instance EBS-backed.
|
263
|
-
if image_data.root_device_type == "ebs"
|
264
|
-
wait_until_volumes_ready(server, state)
|
265
|
-
tag_volumes(server)
|
266
|
-
end
|
267
251
|
wait_until_ready(server, state)
|
268
252
|
end
|
269
253
|
|
@@ -277,7 +261,7 @@ module Kitchen
|
|
277
261
|
|
278
262
|
info("EC2 instance <#{state[:server_id]}> ready (hostname: #{state[:hostname]}).")
|
279
263
|
instance.transport.connection(state).wait_until_ready
|
280
|
-
create_ec2_json(state) if instance.provisioner.name =~ /chef/
|
264
|
+
create_ec2_json(state) if instance.provisioner.name =~ /chef/i
|
281
265
|
debug("ec2:create '#{state[:hostname]}'")
|
282
266
|
rescue Exception
|
283
267
|
# Clean up any auto-created security groups or keys on the way out.
|
@@ -291,14 +275,11 @@ module Kitchen
|
|
291
275
|
server = ec2.get_instance(state[:server_id])
|
292
276
|
unless server.nil?
|
293
277
|
instance.transport.connection(state).close
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
spot_instance_request_ids: [state[:spot_request_id]]
|
300
|
-
)
|
301
|
-
state.delete(:spot_request_id)
|
278
|
+
begin
|
279
|
+
server.terminate
|
280
|
+
rescue ::Aws::EC2::Errors::InvalidInstanceIDNotFound => e
|
281
|
+
warn("Received #{e}, instance was probably already destroyed. Ignoring")
|
282
|
+
end
|
302
283
|
end
|
303
284
|
# If we are going to clean up an automatic security group, we need
|
304
285
|
# to wait for the instance to shut down. This slightly breaks the
|
@@ -405,15 +386,14 @@ module Kitchen
|
|
405
386
|
@instance_generator = Aws::InstanceGenerator.new(config, ec2, instance.logger)
|
406
387
|
end
|
407
388
|
|
408
|
-
#
|
389
|
+
# AWS helper for creating the instance
|
409
390
|
def submit_server
|
410
391
|
instance_data = instance_generator.ec2_instance_data
|
411
392
|
debug("Creating EC2 instance in region #{config[:region]} with properties:")
|
412
393
|
instance_data.each do |key, value|
|
413
394
|
debug("- #{key} = #{value.inspect}")
|
414
395
|
end
|
415
|
-
|
416
|
-
instance_data[:max_count] = 1
|
396
|
+
|
417
397
|
ec2.create_instance(instance_data)
|
418
398
|
end
|
419
399
|
|
@@ -441,7 +421,7 @@ module Kitchen
|
|
441
421
|
configs
|
442
422
|
end
|
443
423
|
|
444
|
-
def submit_spots
|
424
|
+
def submit_spots
|
445
425
|
configs = [config]
|
446
426
|
expanded = []
|
447
427
|
keys = %i{instance_type subnet_id}
|
@@ -454,40 +434,22 @@ module Kitchen
|
|
454
434
|
expanded = []
|
455
435
|
end
|
456
436
|
|
437
|
+
errs = []
|
457
438
|
configs.each do |conf|
|
458
439
|
begin
|
459
440
|
@config = conf
|
460
|
-
return submit_spot
|
461
|
-
rescue
|
441
|
+
return submit_spot
|
442
|
+
rescue => e
|
443
|
+
errs.append(e)
|
462
444
|
end
|
463
445
|
end
|
464
|
-
|
465
|
-
raise "Could not create a spot"
|
446
|
+
raise ["Could not create a spot instance:", errs].flatten.join("\n")
|
466
447
|
end
|
467
448
|
|
468
|
-
def submit_spot
|
449
|
+
def submit_spot
|
469
450
|
debug("Creating EC2 Spot Instance..")
|
451
|
+
instance_data = instance_generator.ec2_instance_data
|
470
452
|
|
471
|
-
spot_request_id = create_spot_request
|
472
|
-
# deleting the instance cancels the request, but deleting the request
|
473
|
-
# does not affect the instance
|
474
|
-
state[:spot_request_id] = spot_request_id
|
475
|
-
ec2.client.wait_until(
|
476
|
-
:spot_instance_request_fulfilled,
|
477
|
-
spot_instance_request_ids: [spot_request_id]
|
478
|
-
) do |w|
|
479
|
-
w.max_attempts = config[:spot_wait] / config[:retryable_sleep]
|
480
|
-
w.delay = config[:retryable_sleep]
|
481
|
-
w.before_attempt do |attempts|
|
482
|
-
c = attempts * config[:retryable_sleep]
|
483
|
-
t = config[:spot_wait]
|
484
|
-
info "Waited #{c}/#{t}s for spot request <#{spot_request_id}> to become fulfilled."
|
485
|
-
end
|
486
|
-
end
|
487
|
-
ec2.get_instance_from_spot_request(spot_request_id)
|
488
|
-
end
|
489
|
-
|
490
|
-
def create_spot_request
|
491
453
|
request_duration = config[:spot_wait]
|
492
454
|
config_spot_price = config[:spot_price].to_s
|
493
455
|
if %w{ondemand on-demand}.include?(config_spot_price)
|
@@ -495,56 +457,36 @@ module Kitchen
|
|
495
457
|
else
|
496
458
|
spot_price = config_spot_price
|
497
459
|
end
|
498
|
-
|
499
|
-
|
500
|
-
launch_specification: instance_generator.ec2_instance_data,
|
460
|
+
spot_options = {
|
461
|
+
spot_instance_type: "persistent", # Cannot use one-time with valid_until
|
501
462
|
valid_until: Time.now + request_duration,
|
463
|
+
instance_interruption_behavior: "stop",
|
502
464
|
}
|
503
465
|
if config[:block_duration_minutes]
|
504
|
-
|
466
|
+
spot_options[:block_duration_minutes] = config[:block_duration_minutes]
|
505
467
|
end
|
506
|
-
|
507
|
-
|
508
|
-
response[:spot_instance_requests][0][:spot_instance_request_id]
|
509
|
-
end
|
510
|
-
|
511
|
-
def tag_server(server)
|
512
|
-
if config[:tags] && !config[:tags].empty?
|
513
|
-
tags = config[:tags].map do |k, v|
|
514
|
-
# we convert the value to a string because
|
515
|
-
# nils should be passed as an empty String
|
516
|
-
# and Integers need to be represented as Strings
|
517
|
-
{ key: k.to_s, value: v.to_s }
|
518
|
-
end
|
519
|
-
server.create_tags(tags: tags)
|
468
|
+
unless spot_price == "" # i.e. on-demand
|
469
|
+
spot_options[:max_price] = spot_price
|
520
470
|
end
|
521
|
-
end
|
522
471
|
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
end
|
528
|
-
server.volumes.each do |volume|
|
529
|
-
volume.create_tags(tags: tags)
|
530
|
-
end
|
531
|
-
end
|
532
|
-
end
|
472
|
+
instance_data[:instance_market_options] = {
|
473
|
+
market_type: "spot",
|
474
|
+
spot_options: spot_options,
|
475
|
+
}
|
533
476
|
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
(described_volume_count > 0) && (described_volume_count == ready_volume_count)
|
477
|
+
# The preferred way to create a spot instance is via request_spot_instances()
|
478
|
+
# However, it does not allow for tagging to occur at creation time.
|
479
|
+
# create_instances() allows creation of tagged spot instances, but does
|
480
|
+
# not retry if the price could not be satisfied immediately.
|
481
|
+
Retryable.retryable(
|
482
|
+
tries: config[:spot_wait] / config[:retryable_sleep],
|
483
|
+
sleep: lambda { |_n| config[:retryable_sleep] },
|
484
|
+
on: ::Aws::EC2::Errors::SpotMaxPriceTooLow
|
485
|
+
) do |retries|
|
486
|
+
c = retries * config[:retryable_sleep]
|
487
|
+
t = config[:spot_wait]
|
488
|
+
info "Waited #{c}/#{t}s for spot request to become fulfilled."
|
489
|
+
ec2.create_instance(instance_data)
|
548
490
|
end
|
549
491
|
end
|
550
492
|
|
@@ -788,6 +730,7 @@ module Kitchen
|
|
788
730
|
elsif config[:subnet_filter]
|
789
731
|
subnets = ec2.client.describe_subnets(filters: [{ name: "tag:#{config[:subnet_filter][:tag]}", values: [config[:subnet_filter][:value]] }]).subnets
|
790
732
|
raise "Subnets with tag '#{config[:subnet_filter][:tag]}=#{config[:subnet_filter][:value]}' not found during security group creation" if subnets.empty?
|
733
|
+
|
791
734
|
subnets.first.vpc_id
|
792
735
|
else
|
793
736
|
# Try to check for a default VPC.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
4
|
#
|
5
|
-
# Copyright::
|
5
|
+
# Copyright:: Chef Software, Inc.
|
6
6
|
# Copyright:: 2012-2018, Fletcher Nichol
|
7
7
|
#
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -22,6 +22,6 @@ module Kitchen
|
|
22
22
|
module Driver
|
23
23
|
|
24
24
|
# Version string for EC2 Test Kitchen driver
|
25
|
-
EC2_VERSION = "3.
|
25
|
+
EC2_VERSION = "3.7.0".freeze
|
26
26
|
end
|
27
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kitchen-ec2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fletcher Nichol
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-kitchen
|
@@ -168,14 +168,14 @@ dependencies:
|
|
168
168
|
requirements:
|
169
169
|
- - '='
|
170
170
|
- !ruby/object:Gem::Version
|
171
|
-
version:
|
171
|
+
version: 1.1.2
|
172
172
|
type: :development
|
173
173
|
prerelease: false
|
174
174
|
version_requirements: !ruby/object:Gem::Requirement
|
175
175
|
requirements:
|
176
176
|
- - '='
|
177
177
|
- !ruby/object:Gem::Version
|
178
|
-
version:
|
178
|
+
version: 1.1.2
|
179
179
|
- !ruby/object:Gem::Dependency
|
180
180
|
name: climate_control
|
181
181
|
requirement: !ruby/object:Gem::Requirement
|
@@ -216,7 +216,7 @@ homepage: https://github.com/test-kitchen/kitchen-ec2
|
|
216
216
|
licenses:
|
217
217
|
- Apache-2.0
|
218
218
|
metadata: {}
|
219
|
-
post_install_message:
|
219
|
+
post_install_message:
|
220
220
|
rdoc_options: []
|
221
221
|
require_paths:
|
222
222
|
- lib
|
@@ -224,15 +224,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
224
224
|
requirements:
|
225
225
|
- - ">="
|
226
226
|
- !ruby/object:Gem::Version
|
227
|
-
version: '2.
|
227
|
+
version: '2.4'
|
228
228
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
229
229
|
requirements:
|
230
230
|
- - ">="
|
231
231
|
- !ruby/object:Gem::Version
|
232
232
|
version: '0'
|
233
233
|
requirements: []
|
234
|
-
rubygems_version: 3.
|
235
|
-
signing_key:
|
234
|
+
rubygems_version: 3.1.2
|
235
|
+
signing_key:
|
236
236
|
specification_version: 4
|
237
237
|
summary: A Test Kitchen Driver for Amazon EC2
|
238
238
|
test_files: []
|