kitchen-ec2 3.16.0 → 3.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/kitchen/driver/aws/client.rb +4 -12
- data/lib/kitchen/driver/aws/dedicated_hosts.rb +4 -4
- data/lib/kitchen/driver/aws/instance_generator.rb +5 -13
- data/lib/kitchen/driver/aws/standard_platform/alma.rb +52 -0
- data/lib/kitchen/driver/aws/standard_platform/amazon.rb +4 -4
- data/lib/kitchen/driver/aws/standard_platform/amazon2.rb +4 -4
- data/lib/kitchen/driver/aws/standard_platform/amazon2023.rb +4 -4
- data/lib/kitchen/driver/aws/standard_platform/centos.rb +4 -4
- data/lib/kitchen/driver/aws/standard_platform/debian.rb +9 -9
- data/lib/kitchen/driver/aws/standard_platform/fedora.rb +4 -4
- data/lib/kitchen/driver/aws/standard_platform/freebsd.rb +4 -4
- data/lib/kitchen/driver/aws/standard_platform/macos.rb +4 -4
- data/lib/kitchen/driver/aws/standard_platform/rhel.rb +5 -5
- data/lib/kitchen/driver/aws/standard_platform/rocky.rb +51 -0
- data/lib/kitchen/driver/aws/standard_platform/ubuntu.rb +4 -4
- data/lib/kitchen/driver/aws/standard_platform/windows.rb +33 -34
- data/lib/kitchen/driver/aws/standard_platform.rb +25 -20
- data/lib/kitchen/driver/ec2.rb +61 -38
- data/lib/kitchen/driver/ec2_version.rb +1 -3
- metadata +27 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: abdd51753a33ae7cf21aeb7f3073cd949d0c0c998eb065955b2bb8982441760a
|
|
4
|
+
data.tar.gz: f8a5ffd49f6213cc5822857f2af830be06fd42fe1c9a29cb60328b0fd4835e45
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b68043de14aab7e71d0b4c4570492e81b0e5b6af6e04ed0ed55df1db476f2f791de20030e0b630919a811c0605f8388719820ed3b7adf87d982b3a53b2b3d230
|
|
7
|
+
data.tar.gz: 74c9d0cea39fccd36f79ea1490f24946eac7ecd2670c0fe2434e1a43110727015e18472839a56b28f351e342d69eb038166edc45ecc00b4e15bfa9f393696461
|
|
@@ -22,16 +22,12 @@ require "aws-sdk-core/shared_credentials"
|
|
|
22
22
|
require "aws-sdk-core/instance_profile_credentials"
|
|
23
23
|
|
|
24
24
|
module Kitchen
|
|
25
|
-
|
|
26
25
|
module Driver
|
|
27
|
-
|
|
28
26
|
class Aws
|
|
29
|
-
|
|
30
27
|
# A class for creating and managing the EC2 client connection
|
|
31
28
|
#
|
|
32
29
|
# @author Tyler Ball <tball@chef.io>
|
|
33
30
|
class Client
|
|
34
|
-
|
|
35
31
|
def initialize(
|
|
36
32
|
region,
|
|
37
33
|
profile_name = "default",
|
|
@@ -40,12 +36,12 @@ module Kitchen
|
|
|
40
36
|
ssl_verify_peer = true
|
|
41
37
|
)
|
|
42
38
|
::Aws.config.update(
|
|
43
|
-
region
|
|
39
|
+
region:,
|
|
44
40
|
profile: profile_name,
|
|
45
|
-
http_proxy
|
|
46
|
-
ssl_verify_peer:
|
|
41
|
+
http_proxy:,
|
|
42
|
+
ssl_verify_peer:
|
|
47
43
|
)
|
|
48
|
-
::Aws.config.update(retry_limit:
|
|
44
|
+
::Aws.config.update(retry_limit:) unless retry_limit.nil?
|
|
49
45
|
end
|
|
50
46
|
|
|
51
47
|
# create a new AWS EC2 instance
|
|
@@ -89,11 +85,7 @@ module Kitchen
|
|
|
89
85
|
def resource
|
|
90
86
|
@resource ||= ::Aws::EC2::Resource.new
|
|
91
87
|
end
|
|
92
|
-
|
|
93
88
|
end
|
|
94
|
-
|
|
95
89
|
end
|
|
96
|
-
|
|
97
90
|
end
|
|
98
|
-
|
|
99
91
|
end
|
|
@@ -98,10 +98,10 @@ module Kitchen
|
|
|
98
98
|
info("Deallocating dedicated host #{host_id}")
|
|
99
99
|
|
|
100
100
|
response = ec2.client.release_hosts({ host_ids: [host_id] })
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
return if response.unsuccessful.empty?
|
|
102
|
+
|
|
103
|
+
warn "ERROR: Could not release dedicated host #{host_id}. Host may remain allocated and incur cost"
|
|
104
|
+
exit!
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
# return instance family from type
|
|
@@ -20,16 +20,12 @@ require "base64" unless defined?(Base64)
|
|
|
20
20
|
require "aws-sdk-ec2"
|
|
21
21
|
|
|
22
22
|
module Kitchen
|
|
23
|
-
|
|
24
23
|
module Driver
|
|
25
|
-
|
|
26
24
|
class Aws
|
|
27
|
-
|
|
28
25
|
# A class for encapsulating the instance payload logic
|
|
29
26
|
#
|
|
30
27
|
# @author Tyler Ball <tball@chef.io>
|
|
31
28
|
class InstanceGenerator
|
|
32
|
-
|
|
33
29
|
attr_reader :config, :ec2, :logger
|
|
34
30
|
|
|
35
31
|
def initialize(config, ec2, logger)
|
|
@@ -42,7 +38,7 @@ module Kitchen
|
|
|
42
38
|
# can be passed in null, others need to be ommitted if they are null
|
|
43
39
|
# Some fields can be passed in null, others need to be ommitted if they are null
|
|
44
40
|
# @return [Hash]
|
|
45
|
-
def ec2_instance_data
|
|
41
|
+
def ec2_instance_data
|
|
46
42
|
# Support for looking up security group id and subnet id using tags.
|
|
47
43
|
vpc_id = nil
|
|
48
44
|
client = ::Aws::EC2::Client.new(region: config[:region])
|
|
@@ -129,8 +125,8 @@ module Kitchen
|
|
|
129
125
|
# and Integers need to be represented as Strings
|
|
130
126
|
{ key: k, value: v.to_s }
|
|
131
127
|
end
|
|
132
|
-
instance_tag_spec = { resource_type: "instance", tags:
|
|
133
|
-
volume_tag_spec = { resource_type: "volume", tags:
|
|
128
|
+
instance_tag_spec = { resource_type: "instance", tags: }
|
|
129
|
+
volume_tag_spec = { resource_type: "volume", tags: }
|
|
134
130
|
i[:tag_specifications] = [instance_tag_spec, volume_tag_spec]
|
|
135
131
|
end
|
|
136
132
|
|
|
@@ -146,7 +142,7 @@ module Kitchen
|
|
|
146
142
|
if i.key?(:placement)
|
|
147
143
|
i[:placement][:tenancy] = tenancy
|
|
148
144
|
else
|
|
149
|
-
i[:placement] = { tenancy:
|
|
145
|
+
i[:placement] = { tenancy: }
|
|
150
146
|
end
|
|
151
147
|
end
|
|
152
148
|
unless config[:block_device_mappings].nil? || config[:block_device_mappings].empty?
|
|
@@ -190,7 +186,7 @@ module Kitchen
|
|
|
190
186
|
if i.key?(:placement)
|
|
191
187
|
i[:placement][:tenancy] = tenancy
|
|
192
188
|
else
|
|
193
|
-
i[:placement] = { tenancy:
|
|
189
|
+
i[:placement] = { tenancy: }
|
|
194
190
|
end
|
|
195
191
|
end
|
|
196
192
|
unless config[:instance_initiated_shutdown_behavior].nil? ||
|
|
@@ -212,11 +208,7 @@ module Kitchen
|
|
|
212
208
|
|
|
213
209
|
@user_data = Base64.encode64(raw_user_data)
|
|
214
210
|
end
|
|
215
|
-
|
|
216
211
|
end
|
|
217
|
-
|
|
218
212
|
end
|
|
219
|
-
|
|
220
213
|
end
|
|
221
|
-
|
|
222
214
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright:: 2023, Jared Kauppila
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require_relative "../standard_platform"
|
|
17
|
+
|
|
18
|
+
module Kitchen
|
|
19
|
+
module Driver
|
|
20
|
+
class Aws
|
|
21
|
+
class StandardPlatform
|
|
22
|
+
# https://wiki.almalinux.org/cloud/AWS.html
|
|
23
|
+
class Alma < StandardPlatform
|
|
24
|
+
StandardPlatform.platforms["alma"] = self
|
|
25
|
+
StandardPlatform.platforms["almalinux"] = self
|
|
26
|
+
|
|
27
|
+
# default username for this platform's ami
|
|
28
|
+
# @return [String]
|
|
29
|
+
def username
|
|
30
|
+
"ec2-user"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def image_search
|
|
34
|
+
search = {
|
|
35
|
+
"owner-id" => "764336703387",
|
|
36
|
+
"name" => version ? "AlmaLinux OS #{version}*" : "AlmaLinux OS *",
|
|
37
|
+
}
|
|
38
|
+
search["architecture"] = architecture if architecture
|
|
39
|
+
search
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.from_image(driver, image)
|
|
43
|
+
return unless /AlmaLinux OS/i.match?(image.name)
|
|
44
|
+
|
|
45
|
+
image.name =~ /\b(\d+(\.\d+)?)\b/i
|
|
46
|
+
new(driver, "alma", (Regexp.last_match || [])[1], image.architecture)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -39,10 +39,10 @@ module Kitchen
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def self.from_image(driver, image)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
return unless /amzn-ami/i.match?(image.name)
|
|
43
|
+
|
|
44
|
+
image.name =~ /\b(\d+(\.\d+[\.\d])?)/i
|
|
45
|
+
new(driver, "amazon", (Regexp.last_match || [])[1], image.architecture)
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -39,10 +39,10 @@ module Kitchen
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def self.from_image(driver, image)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
return unless /amzn2-ami/i.match?(image.name)
|
|
43
|
+
|
|
44
|
+
image.name =~ /\b(\d+(\.\d+[\.\d])?)/i
|
|
45
|
+
new(driver, "amazon2", (Regexp.last_match || [])[1], image.architecture)
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -39,10 +39,10 @@ module Kitchen
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def self.from_image(driver, image)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
return unless /al2023-ami/i.match?(image.name)
|
|
43
|
+
|
|
44
|
+
image.name =~ /\b(\d+(\.\d+[\.\d])?)/i
|
|
45
|
+
new(driver, "amazon2023", (Regexp.last_match || [])[1], image.architecture)
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -52,10 +52,10 @@ module Kitchen
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def self.from_image(driver, image)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
return unless /centos/i.match?(image.name)
|
|
56
|
+
|
|
57
|
+
image.name =~ /\b(\d+(\.\d+)?)\b/i
|
|
58
|
+
new(driver, "centos", (Regexp.last_match || [])[1], image.architecture)
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -73,16 +73,16 @@ module Kitchen
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def self.from_image(driver, image)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
end
|
|
84
|
-
new(driver, "debian", version, image.architecture)
|
|
76
|
+
return unless /debian/i.match?(image.name)
|
|
77
|
+
|
|
78
|
+
image.name =~ /\b(\d+|#{DEBIAN_CODENAMES.values.join("|")})\b/i
|
|
79
|
+
version = (Regexp.last_match || [])[1]
|
|
80
|
+
if version&.to_i&.zero?
|
|
81
|
+
version = DEBIAN_CODENAMES.find do |_v, codename|
|
|
82
|
+
codename == version.downcase
|
|
83
|
+
end.first
|
|
85
84
|
end
|
|
85
|
+
new(driver, "debian", version, image.architecture)
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
88
|
end
|
|
@@ -39,10 +39,10 @@ module Kitchen
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def self.from_image(driver, image)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
return unless /fedora/i.match?(image.name)
|
|
43
|
+
|
|
44
|
+
image.name =~ /\b(\d+(\.\d+)?)\b/i
|
|
45
|
+
new(driver, "fedora", (Regexp.last_match || [])[1], image.architecture)
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -41,10 +41,10 @@ module Kitchen
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def self.from_image(driver, image)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
return unless /freebsd/i.match?(image.name)
|
|
45
|
+
|
|
46
|
+
image.name =~ /\b(\d+(\.\d+)?)\b/i
|
|
47
|
+
new(driver, "freebsd", (Regexp.last_match || [])[1], image.architecture)
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
end
|
|
@@ -39,10 +39,10 @@ module Kitchen
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def self.from_image(driver, image)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
return unless /amzn-ec2-macos/i.match?(image.name)
|
|
43
|
+
|
|
44
|
+
image.name =~ /\b(\d+(\.\d+[\.\d])?)/i
|
|
45
|
+
new(driver, "macos", (Regexp.last_match || [])[1], image.architecture)
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -32,7 +32,7 @@ module Kitchen
|
|
|
32
32
|
# default username for this platform's ami
|
|
33
33
|
# @return [String]
|
|
34
34
|
def username
|
|
35
|
-
|
|
35
|
+
version && version.to_f < 6.4 ? "root" : "ec2-user"
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def image_search
|
|
@@ -45,10 +45,10 @@ module Kitchen
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def self.from_image(driver, image)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
return unless /rhel/i.match?(image.name)
|
|
49
|
+
|
|
50
|
+
image.name =~ /\b(\d+(\.\d+)?)/i
|
|
51
|
+
new(driver, "rhel", (Regexp.last_match || [])[1], image.architecture)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def sort_by_version(images)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright:: 2023, Jared Kauppila
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
require_relative "../standard_platform"
|
|
17
|
+
|
|
18
|
+
module Kitchen
|
|
19
|
+
module Driver
|
|
20
|
+
class Aws
|
|
21
|
+
class StandardPlatform
|
|
22
|
+
class Rocky < StandardPlatform
|
|
23
|
+
StandardPlatform.platforms["rocky"] = self
|
|
24
|
+
StandardPlatform.platforms["rockylinux"] = self
|
|
25
|
+
|
|
26
|
+
# default username for this platform's ami
|
|
27
|
+
# @return [String]
|
|
28
|
+
def username
|
|
29
|
+
"rocky"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def image_search
|
|
33
|
+
search = {
|
|
34
|
+
"owner-id" => "792107900819",
|
|
35
|
+
"name" => version ? "Rocky-#{version}-*" : "Rocky-*",
|
|
36
|
+
}
|
|
37
|
+
search["architecture"] = architecture if architecture
|
|
38
|
+
search
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.from_image(driver, image)
|
|
42
|
+
return unless /Rocky-/i.match?(image.name)
|
|
43
|
+
|
|
44
|
+
image.name =~ /\b(\d+(\.\d+[\.\d])?)/i
|
|
45
|
+
new(driver, "rocky", (Regexp.last_match || [])[1], image.architecture)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -39,10 +39,10 @@ module Kitchen
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def self.from_image(driver, image)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
return unless /ubuntu/i.match?(image.name)
|
|
43
|
+
|
|
44
|
+
image.name =~ /\b(\d+(\.\d+)?)\b/i
|
|
45
|
+
new(driver, "ubuntu", (Regexp.last_match || [])[1], image.architecture)
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -70,21 +70,20 @@ module Kitchen
|
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
def self.from_image(driver, image)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
new(driver, "windows", version, image.architecture)
|
|
73
|
+
return unless /Windows/i.match?(image.name)
|
|
74
|
+
|
|
75
|
+
# 2008 R2 SP2
|
|
76
|
+
if image.name =~ /(\b\d+)\W*(r\d+)?/i
|
|
77
|
+
major = (Regexp.last_match || [])[1]
|
|
78
|
+
revision = (Regexp.last_match || [])[2]
|
|
79
|
+
service_pack = (Regexp.last_match || [])[1] if image.name =~ /(sp\d+|rtm)/i
|
|
80
|
+
revision = revision.downcase if revision
|
|
81
|
+
service_pack ||= "rtm"
|
|
82
|
+
service_pack = service_pack.downcase
|
|
83
|
+
version = "#{major}#{revision}#{service_pack}"
|
|
87
84
|
end
|
|
85
|
+
|
|
86
|
+
new(driver, "windows", version, image.architecture)
|
|
88
87
|
end
|
|
89
88
|
|
|
90
89
|
protected
|
|
@@ -132,30 +131,30 @@ module Kitchen
|
|
|
132
131
|
|
|
133
132
|
private
|
|
134
133
|
|
|
135
|
-
def windows_name_filter
|
|
134
|
+
def windows_name_filter
|
|
136
135
|
major, revision, service_pack = windows_version_parts
|
|
137
|
-
if
|
|
136
|
+
if [2022, 2019, 2016].include?(major)
|
|
138
137
|
"Windows_Server-#{major}-English-Full-Base-*"
|
|
139
|
-
elsif
|
|
138
|
+
elsif [1709, 1803].include?(major)
|
|
140
139
|
"Windows_Server-#{major}-English-Core-ContainersLatest-*"
|
|
141
140
|
else
|
|
142
|
-
case revision
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
case service_pack
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
141
|
+
revision_strings = case revision
|
|
142
|
+
when nil
|
|
143
|
+
["", "R*_"]
|
|
144
|
+
when 0
|
|
145
|
+
[""]
|
|
146
|
+
else
|
|
147
|
+
["R#{revision}_"]
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
revision_strings = case service_pack
|
|
151
|
+
when nil
|
|
152
|
+
revision_strings.flat_map { |r| ["#{r}RTM", "#{r}SP*"] }
|
|
153
|
+
when 0
|
|
154
|
+
revision_strings.map { |r| "#{r}RTM" }
|
|
155
|
+
else
|
|
156
|
+
revision_strings.map { |r| "#{r}SP#{service_pack}" }
|
|
157
|
+
end
|
|
159
158
|
|
|
160
159
|
name_filter = revision_strings.map do |r|
|
|
161
160
|
"Windows_Server-#{major || "*"}-#{r}-English-*-Base-*"
|
|
@@ -91,6 +91,11 @@ module Kitchen
|
|
|
91
91
|
#
|
|
92
92
|
SUPPORTED_ARCHITECTURES = %w{x86_64 i386 arm64}.freeze
|
|
93
93
|
|
|
94
|
+
#
|
|
95
|
+
# The list of supported ebs volume types
|
|
96
|
+
#
|
|
97
|
+
EBS_VOLUME_TYPES = %w{gp3 gp2}.freeze
|
|
98
|
+
|
|
94
99
|
#
|
|
95
100
|
# Find the best matching image for the given image search.
|
|
96
101
|
#
|
|
@@ -103,12 +108,12 @@ module Kitchen
|
|
|
103
108
|
end
|
|
104
109
|
|
|
105
110
|
# We prefer most recent first
|
|
106
|
-
images = driver.ec2.resource.images(filters:
|
|
111
|
+
images = driver.ec2.resource.images(filters:)
|
|
107
112
|
images = sort_images(images)
|
|
108
113
|
show_returned_images(images)
|
|
109
114
|
|
|
110
115
|
# Grab the best match
|
|
111
|
-
images.first
|
|
116
|
+
images.first&.id
|
|
112
117
|
end
|
|
113
118
|
|
|
114
119
|
#
|
|
@@ -136,9 +141,9 @@ module Kitchen
|
|
|
136
141
|
#
|
|
137
142
|
def self.from_platform_string(driver, platform_string)
|
|
138
143
|
platform, version, architecture = parse_platform_string(platform_string)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
return unless platform && platforms[platform]
|
|
145
|
+
|
|
146
|
+
platforms[platform].new(driver, platform, version, architecture)
|
|
142
147
|
end
|
|
143
148
|
|
|
144
149
|
#
|
|
@@ -157,6 +162,20 @@ module Kitchen
|
|
|
157
162
|
nil
|
|
158
163
|
end
|
|
159
164
|
|
|
165
|
+
def self.parse_platform_string(platform_string)
|
|
166
|
+
platform, version = platform_string.split("-", 2)
|
|
167
|
+
|
|
168
|
+
# If the right side is a valid architecture, use it as such
|
|
169
|
+
# i.e. debian-i386 or windows-server-2012r2-i386
|
|
170
|
+
if version && SUPPORTED_ARCHITECTURES.include?(version.split("-")[-1])
|
|
171
|
+
# server-2012r2-i386 -> server-2012r2, -, i386
|
|
172
|
+
version, _dash, architecture = version.rpartition("-")
|
|
173
|
+
version = nil if version == ""
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
[platform, version, architecture]
|
|
177
|
+
end
|
|
178
|
+
|
|
160
179
|
protected
|
|
161
180
|
|
|
162
181
|
#
|
|
@@ -192,20 +211,6 @@ module Kitchen
|
|
|
192
211
|
|
|
193
212
|
private
|
|
194
213
|
|
|
195
|
-
def self.parse_platform_string(platform_string)
|
|
196
|
-
platform, version = platform_string.split("-", 2)
|
|
197
|
-
|
|
198
|
-
# If the right side is a valid architecture, use it as such
|
|
199
|
-
# i.e. debian-i386 or windows-server-2012r2-i386
|
|
200
|
-
if version && SUPPORTED_ARCHITECTURES.include?(version.split("-")[-1])
|
|
201
|
-
# server-2012r2-i386 -> server-2012r2, -, i386
|
|
202
|
-
version, _dash, architecture = version.rpartition("-")
|
|
203
|
-
version = nil if version == ""
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
[platform, version, architecture]
|
|
207
|
-
end
|
|
208
|
-
|
|
209
214
|
def sort_images(images)
|
|
210
215
|
# P6: We prefer more recent images over older ones
|
|
211
216
|
images = images.sort_by(&:creation_date).reverse
|
|
@@ -214,7 +219,7 @@ module Kitchen
|
|
|
214
219
|
# P4: We prefer (SSD) (if available)
|
|
215
220
|
images = prefer(images) do |image|
|
|
216
221
|
image.block_device_mappings.any? do |b|
|
|
217
|
-
b.device_name == image.root_device_name && b.ebs &&
|
|
222
|
+
b.device_name == image.root_device_name && b.ebs && EBS_VOLUME_TYPES.any?(b.ebs.volume_type)
|
|
218
223
|
end
|
|
219
224
|
end
|
|
220
225
|
# P3: We prefer ebs over instance_store (if available)
|
data/lib/kitchen/driver/ec2.rb
CHANGED
|
@@ -24,12 +24,14 @@ require_relative "aws/client"
|
|
|
24
24
|
require_relative "aws/dedicated_hosts"
|
|
25
25
|
require_relative "aws/instance_generator"
|
|
26
26
|
require_relative "aws/standard_platform"
|
|
27
|
+
require_relative "aws/standard_platform/alma"
|
|
27
28
|
require_relative "aws/standard_platform/amazon"
|
|
28
29
|
require_relative "aws/standard_platform/amazon2"
|
|
29
30
|
require_relative "aws/standard_platform/amazon2023"
|
|
30
31
|
require_relative "aws/standard_platform/centos"
|
|
31
32
|
require_relative "aws/standard_platform/debian"
|
|
32
33
|
require_relative "aws/standard_platform/rhel"
|
|
34
|
+
require_relative "aws/standard_platform/rocky"
|
|
33
35
|
require_relative "aws/standard_platform/fedora"
|
|
34
36
|
require_relative "aws/standard_platform/freebsd"
|
|
35
37
|
require_relative "aws/standard_platform/macos"
|
|
@@ -43,20 +45,17 @@ require "etc" unless defined?(Etc)
|
|
|
43
45
|
require "socket" unless defined?(Socket)
|
|
44
46
|
|
|
45
47
|
module Kitchen
|
|
46
|
-
|
|
47
48
|
module Driver
|
|
48
|
-
|
|
49
49
|
# Amazon EC2 driver for Test Kitchen.
|
|
50
50
|
#
|
|
51
51
|
# @author Fletcher Nichol <fnichol@nichol.ca>
|
|
52
52
|
class Ec2 < Kitchen::Driver::Base
|
|
53
|
-
|
|
54
53
|
kitchen_driver_api_version 2
|
|
55
54
|
|
|
56
55
|
plugin_version Kitchen::Driver::EC2_VERSION
|
|
57
56
|
|
|
58
57
|
default_config :region, ENV["AWS_REGION"] || "us-east-1"
|
|
59
|
-
default_config :shared_credentials_profile, ENV
|
|
58
|
+
default_config :shared_credentials_profile, ENV.fetch("AWS_PROFILE", nil)
|
|
60
59
|
default_config :availability_zone, nil
|
|
61
60
|
default_config :instance_type, &:default_instance_type
|
|
62
61
|
default_config :ebs_optimized, false
|
|
@@ -80,14 +79,14 @@ module Kitchen
|
|
|
80
79
|
default_config :aws_access_key_id, nil
|
|
81
80
|
default_config :aws_secret_access_key, nil
|
|
82
81
|
default_config :aws_session_token, nil
|
|
83
|
-
default_config :aws_ssh_key_id, ENV
|
|
82
|
+
default_config :aws_ssh_key_id, ENV.fetch("AWS_SSH_KEY_ID", nil)
|
|
84
83
|
default_config :aws_ssh_key_type, "rsa"
|
|
85
84
|
default_config :image_id, &:default_ami
|
|
86
85
|
default_config :image_search, nil
|
|
87
86
|
default_config :username, nil
|
|
88
87
|
default_config :associate_public_ip, nil
|
|
89
88
|
default_config :interface, nil
|
|
90
|
-
default_config :http_proxy, ENV["HTTPS_PROXY"] || ENV
|
|
89
|
+
default_config :http_proxy, ENV["HTTPS_PROXY"] || ENV.fetch("HTTP_PROXY", nil)
|
|
91
90
|
default_config :retry_limit, 3
|
|
92
91
|
default_config :tenancy, "default"
|
|
93
92
|
default_config :instance_initiated_shutdown_behavior, nil
|
|
@@ -192,10 +191,10 @@ module Kitchen
|
|
|
192
191
|
end
|
|
193
192
|
|
|
194
193
|
# empty keys cause failures when tagging and they make no sense
|
|
195
|
-
validations[:tags] = lambda do |
|
|
194
|
+
validations[:tags] = lambda do |_attr, val, _driver|
|
|
196
195
|
# if someone puts the tags each on their own line it's an array not a hash
|
|
197
196
|
# @todo we should probably just do the right thing and support this format
|
|
198
|
-
if val.
|
|
197
|
+
if val.instance_of?(Array)
|
|
199
198
|
warn "AWS instance tags must be specified as a single hash, not a tag " \
|
|
200
199
|
"on each line. Example: {:foo => 'bar', :bar => 'foo'}"
|
|
201
200
|
exit!
|
|
@@ -245,13 +244,13 @@ module Kitchen
|
|
|
245
244
|
info("Auto placement on one dedicated host out of: #{hosts_with_capacity.map(&:host_id).join(", ")}")
|
|
246
245
|
end
|
|
247
246
|
|
|
248
|
-
if config[:spot_price]
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
247
|
+
server = if config[:spot_price]
|
|
248
|
+
# Spot instance when a price is set
|
|
249
|
+
with_request_limit_backoff(state) { submit_spots }
|
|
250
|
+
else
|
|
251
|
+
# On-demand instance
|
|
252
|
+
with_request_limit_backoff(state) { submit_server }
|
|
253
|
+
end
|
|
255
254
|
info("Instance <#{server.id}> requested.")
|
|
256
255
|
with_request_limit_backoff(state) do
|
|
257
256
|
logging_proc = ->(attempts) { info("Polling AWS for existence, attempt #{attempts}...") }
|
|
@@ -267,7 +266,7 @@ module Kitchen
|
|
|
267
266
|
tries: 10,
|
|
268
267
|
sleep: lambda { |n| [2**n, 30].min },
|
|
269
268
|
on: ::Aws::EC2::Errors::InvalidInstanceIDNotFound
|
|
270
|
-
) do |
|
|
269
|
+
) do |_r, _|
|
|
271
270
|
wait_until_ready(server, state)
|
|
272
271
|
end
|
|
273
272
|
|
|
@@ -318,10 +317,10 @@ module Kitchen
|
|
|
318
317
|
delete_key(state)
|
|
319
318
|
|
|
320
319
|
# Clean up dedicated hosts matching instance_type and unused (if allowed)
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
320
|
+
return unless config[:tenancy] == "host" && allow_deallocate_host?
|
|
321
|
+
|
|
322
|
+
empty_hosts = hosts_with_capacity.select { |host| host_unused?(host) }
|
|
323
|
+
empty_hosts.each { |host| deallocate_host(host.host_id) }
|
|
325
324
|
end
|
|
326
325
|
|
|
327
326
|
def image
|
|
@@ -425,7 +424,7 @@ module Kitchen
|
|
|
425
424
|
def expand_config(conf, key)
|
|
426
425
|
configs = []
|
|
427
426
|
|
|
428
|
-
if conf[key]
|
|
427
|
+
if conf[key].is_a?(Array)
|
|
429
428
|
values = conf[key]
|
|
430
429
|
values.each do |value|
|
|
431
430
|
new_config = conf.clone
|
|
@@ -497,11 +496,11 @@ module Kitchen
|
|
|
497
496
|
instance_data = instance_generator.ec2_instance_data
|
|
498
497
|
|
|
499
498
|
config_spot_price = config[:spot_price].to_s
|
|
500
|
-
if %w{ondemand on-demand}.include?(config_spot_price)
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
499
|
+
spot_price = if %w{ondemand on-demand}.include?(config_spot_price)
|
|
500
|
+
""
|
|
501
|
+
else
|
|
502
|
+
config_spot_price
|
|
503
|
+
end
|
|
505
504
|
spot_options = {
|
|
506
505
|
# Must use one-time in order to use instance_interruption_behavior=terminate
|
|
507
506
|
# spot_instance_type: "one-time", # default
|
|
@@ -517,7 +516,7 @@ module Kitchen
|
|
|
517
516
|
|
|
518
517
|
instance_data[:instance_market_options] = {
|
|
519
518
|
market_type: "spot",
|
|
520
|
-
spot_options
|
|
519
|
+
spot_options:,
|
|
521
520
|
}
|
|
522
521
|
|
|
523
522
|
# The preferred way to create a spot instance is via request_spot_instances()
|
|
@@ -549,7 +548,7 @@ module Kitchen
|
|
|
549
548
|
aws_instance.state.name == "running" &&
|
|
550
549
|
hostname != "0.0.0.0"
|
|
551
550
|
|
|
552
|
-
if ready && (
|
|
551
|
+
if ready && (hostname.nil? || hostname == "")
|
|
553
552
|
debug("Unable to detect hostname using interface_type #{config[:interface]}. Fallback to ordered mapping")
|
|
554
553
|
state[:hostname] = hostname(aws_instance, nil)
|
|
555
554
|
end
|
|
@@ -565,7 +564,7 @@ module Kitchen
|
|
|
565
564
|
output = Base64.decode64(output)
|
|
566
565
|
debug "Console output: --- \n#{output}"
|
|
567
566
|
end
|
|
568
|
-
ready = !!(output
|
|
567
|
+
ready = !!(output.include?("Windows is Ready to use"))
|
|
569
568
|
end
|
|
570
569
|
end
|
|
571
570
|
ready
|
|
@@ -598,7 +597,7 @@ module Kitchen
|
|
|
598
597
|
end
|
|
599
598
|
|
|
600
599
|
def fetch_windows_admin_password(server, state)
|
|
601
|
-
wait_with_destroy(server, state, "to fetch windows admin password") do |
|
|
600
|
+
wait_with_destroy(server, state, "to fetch windows admin password") do |_aws_instance|
|
|
602
601
|
enc = server.client.get_password_data(
|
|
603
602
|
instance_id: state[:server_id]
|
|
604
603
|
).password_data
|
|
@@ -653,7 +652,7 @@ module Kitchen
|
|
|
653
652
|
server.send(interface_type)
|
|
654
653
|
else
|
|
655
654
|
potential_hostname = nil
|
|
656
|
-
INTERFACE_TYPES.
|
|
655
|
+
INTERFACE_TYPES.each_value do |type|
|
|
657
656
|
potential_hostname ||= server.send(type)
|
|
658
657
|
# AWS returns an empty string if the dns name isn't populated yet
|
|
659
658
|
potential_hostname = nil if potential_hostname == ""
|
|
@@ -715,7 +714,7 @@ module Kitchen
|
|
|
715
714
|
|
|
716
715
|
# Preparing custom static admin user if we defined something other than Administrator
|
|
717
716
|
custom_admin_script = ""
|
|
718
|
-
if
|
|
717
|
+
if instance.transport[:username] !~ /administrator/i && instance.transport[:password]
|
|
719
718
|
custom_admin_script = Kitchen::Util.outdent!(<<-EOH)
|
|
720
719
|
"Disabling Complex Passwords" >> $logfile
|
|
721
720
|
$seccfg = [IO.Path]::GetTempFileName()
|
|
@@ -757,7 +756,7 @@ module Kitchen
|
|
|
757
756
|
def image_info(image)
|
|
758
757
|
root_device = image.block_device_mappings
|
|
759
758
|
.find { |b| b.device_name == image.root_device_name }
|
|
760
|
-
volume_type = " #{root_device.ebs.volume_type}" if root_device
|
|
759
|
+
volume_type = " #{root_device.ebs.volume_type}" if root_device&.ebs
|
|
761
760
|
|
|
762
761
|
" Architecture: #{image.architecture}," \
|
|
763
762
|
" Virtualization: #{image.virtualization_type}," \
|
|
@@ -811,6 +810,17 @@ module Kitchen
|
|
|
811
810
|
params = {
|
|
812
811
|
group_name: "kitchen-#{Array.new(8) { rand(36).to_s(36) }.join}",
|
|
813
812
|
description: "Test Kitchen for #{instance.name} by #{Etc.getlogin || "nologin"} on #{Socket.gethostname}",
|
|
813
|
+
tag_specifications: [
|
|
814
|
+
{
|
|
815
|
+
resource_type: "security-group",
|
|
816
|
+
tags: [
|
|
817
|
+
{
|
|
818
|
+
key: "created-by",
|
|
819
|
+
value: "test-kitchen",
|
|
820
|
+
},
|
|
821
|
+
],
|
|
822
|
+
},
|
|
823
|
+
],
|
|
814
824
|
}
|
|
815
825
|
params[:vpc_id] = vpc_id if vpc_id
|
|
816
826
|
resp = ec2.client.create_security_group(params)
|
|
@@ -827,7 +837,7 @@ module Kitchen
|
|
|
827
837
|
from_port: port,
|
|
828
838
|
to_port: port,
|
|
829
839
|
ip_ranges: Array(config[:security_group_cidr_ip]).map do |cidr_ip|
|
|
830
|
-
{ cidr_ip:
|
|
840
|
+
{ cidr_ip: }
|
|
831
841
|
end,
|
|
832
842
|
}
|
|
833
843
|
end
|
|
@@ -849,14 +859,28 @@ module Kitchen
|
|
|
849
859
|
(Etc.getlogin || "nologin").gsub(/\W/, ""),
|
|
850
860
|
Socket.gethostname.gsub(/\W/, "")[0..20],
|
|
851
861
|
Time.now.utc.iso8601,
|
|
852
|
-
Array.new(8) { rand(36).to_s(36) }.join
|
|
862
|
+
Array.new(8) { rand(36).to_s(36) }.join,
|
|
853
863
|
]
|
|
854
864
|
# In a perfect world this would generate the key locally and use ImportKey
|
|
855
865
|
# instead for better security, but given the use case that is very likely
|
|
856
866
|
# to rapidly exhaust local entropy by creating a lot of keys. So this is
|
|
857
867
|
# probably fine. If you want very high security, probably don't use this
|
|
858
868
|
# feature anyway.
|
|
859
|
-
resp = ec2.client.create_key_pair(
|
|
869
|
+
resp = ec2.client.create_key_pair(
|
|
870
|
+
key_name: "kitchen-#{name_parts.join("-")}",
|
|
871
|
+
key_type: config[:aws_ssh_key_type],
|
|
872
|
+
tag_specifications: [
|
|
873
|
+
{
|
|
874
|
+
resource_type: "key-pair",
|
|
875
|
+
tags: [
|
|
876
|
+
{
|
|
877
|
+
key: "created-by",
|
|
878
|
+
value: "test-kitchen",
|
|
879
|
+
},
|
|
880
|
+
],
|
|
881
|
+
},
|
|
882
|
+
]
|
|
883
|
+
)
|
|
860
884
|
state[:auto_key_id] = resp.key_name
|
|
861
885
|
info("Created automatic key pair #{state[:auto_key_id]}")
|
|
862
886
|
# Write the key out with safe permissions
|
|
@@ -890,7 +914,7 @@ module Kitchen
|
|
|
890
914
|
puts "ENI #{config[:elastic_network_interface_id]} already attached."
|
|
891
915
|
end
|
|
892
916
|
rescue ::Aws::EC2::Errors::InvalidNetworkInterfaceIDNotFound => e
|
|
893
|
-
warn(
|
|
917
|
+
warn(e.to_s)
|
|
894
918
|
end
|
|
895
919
|
end
|
|
896
920
|
|
|
@@ -920,7 +944,6 @@ module Kitchen
|
|
|
920
944
|
state.delete(:auto_key_id)
|
|
921
945
|
File.unlink("#{config[:kitchen_root]}/.kitchen/#{instance.name}.pem")
|
|
922
946
|
end
|
|
923
|
-
|
|
924
947
|
end
|
|
925
948
|
end
|
|
926
949
|
end
|
metadata
CHANGED
|
@@ -1,35 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kitchen-ec2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.17.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Test Kitchen Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-11-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: test-kitchen
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - ">="
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: 1.4.1
|
|
20
|
-
- - "<"
|
|
21
|
-
- !ruby/object:Gem::Version
|
|
22
|
-
version: '4'
|
|
23
|
-
type: :runtime
|
|
24
|
-
prerelease: false
|
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
-
requirements:
|
|
27
|
-
- - ">="
|
|
28
|
-
- !ruby/object:Gem::Version
|
|
29
|
-
version: 1.4.1
|
|
30
|
-
- - "<"
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '4'
|
|
33
13
|
- !ruby/object:Gem::Dependency
|
|
34
14
|
name: aws-sdk-ec2
|
|
35
15
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -64,9 +44,29 @@ dependencies:
|
|
|
64
44
|
- - "<"
|
|
65
45
|
- !ruby/object:Gem::Version
|
|
66
46
|
version: '4.0'
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: test-kitchen
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 1.4.1
|
|
54
|
+
- - "<"
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '4'
|
|
57
|
+
type: :runtime
|
|
58
|
+
prerelease: false
|
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: 1.4.1
|
|
64
|
+
- - "<"
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '4'
|
|
67
67
|
description: A Test Kitchen Driver for Amazon EC2
|
|
68
68
|
email:
|
|
69
|
-
-
|
|
69
|
+
- help@sous-chefs.org
|
|
70
70
|
executables: []
|
|
71
71
|
extensions: []
|
|
72
72
|
extra_rdoc_files: []
|
|
@@ -76,6 +76,7 @@ files:
|
|
|
76
76
|
- lib/kitchen/driver/aws/dedicated_hosts.rb
|
|
77
77
|
- lib/kitchen/driver/aws/instance_generator.rb
|
|
78
78
|
- lib/kitchen/driver/aws/standard_platform.rb
|
|
79
|
+
- lib/kitchen/driver/aws/standard_platform/alma.rb
|
|
79
80
|
- lib/kitchen/driver/aws/standard_platform/amazon.rb
|
|
80
81
|
- lib/kitchen/driver/aws/standard_platform/amazon2.rb
|
|
81
82
|
- lib/kitchen/driver/aws/standard_platform/amazon2023.rb
|
|
@@ -85,6 +86,7 @@ files:
|
|
|
85
86
|
- lib/kitchen/driver/aws/standard_platform/freebsd.rb
|
|
86
87
|
- lib/kitchen/driver/aws/standard_platform/macos.rb
|
|
87
88
|
- lib/kitchen/driver/aws/standard_platform/rhel.rb
|
|
89
|
+
- lib/kitchen/driver/aws/standard_platform/rocky.rb
|
|
88
90
|
- lib/kitchen/driver/aws/standard_platform/ubuntu.rb
|
|
89
91
|
- lib/kitchen/driver/aws/standard_platform/windows.rb
|
|
90
92
|
- lib/kitchen/driver/ec2.rb
|
|
@@ -108,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
108
110
|
- !ruby/object:Gem::Version
|
|
109
111
|
version: '0'
|
|
110
112
|
requirements: []
|
|
111
|
-
rubygems_version: 3.4.
|
|
113
|
+
rubygems_version: 3.4.10
|
|
112
114
|
signing_key:
|
|
113
115
|
specification_version: 4
|
|
114
116
|
summary: A Test Kitchen Driver for Amazon EC2
|