kitchen-ec2 3.22.3 → 3.22.4
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 +23 -1
- data/lib/kitchen/driver/aws/dedicated_hosts.rb +74 -29
- data/lib/kitchen/driver/aws/instance_connect.rb +16 -0
- data/lib/kitchen/driver/aws/instance_generator.rb +42 -20
- data/lib/kitchen/driver/aws/ssm_session_manager.rb +20 -3
- data/lib/kitchen/driver/aws/standard_platform/alma.rb +21 -2
- data/lib/kitchen/driver/aws/standard_platform/amazon.rb +26 -3
- data/lib/kitchen/driver/aws/standard_platform/amazon2.rb +26 -3
- data/lib/kitchen/driver/aws/standard_platform/amazon2023.rb +26 -3
- data/lib/kitchen/driver/aws/standard_platform/centos.rb +35 -2
- data/lib/kitchen/driver/aws/standard_platform/debian.rb +44 -5
- data/lib/kitchen/driver/aws/standard_platform/fedora.rb +21 -2
- data/lib/kitchen/driver/aws/standard_platform/freebsd.rb +27 -2
- data/lib/kitchen/driver/aws/standard_platform/macos.rb +30 -4
- data/lib/kitchen/driver/aws/standard_platform/rhel.rb +40 -2
- data/lib/kitchen/driver/aws/standard_platform/rocky.rb +30 -3
- data/lib/kitchen/driver/aws/standard_platform/ubuntu.rb +21 -2
- data/lib/kitchen/driver/aws/standard_platform/windows.rb +67 -34
- data/lib/kitchen/driver/aws/standard_platform.rb +46 -2
- data/lib/kitchen/driver/ec2.rb +332 -10
- data/lib/kitchen/driver/ec2_version.rb +1 -1
- metadata +2 -2
|
@@ -23,6 +23,12 @@ module Kitchen
|
|
|
23
23
|
class Debian < StandardPlatform
|
|
24
24
|
StandardPlatform.platforms["debian"] = self
|
|
25
25
|
|
|
26
|
+
# Debian release numbers to their codenames, newest first.
|
|
27
|
+
#
|
|
28
|
+
# The order matters: the first entry is the newest known release and
|
|
29
|
+
# is what an unversioned Debian platform resolves to.
|
|
30
|
+
#
|
|
31
|
+
# @return [Hash{Integer => String}]
|
|
26
32
|
DEBIAN_CODENAMES = {
|
|
27
33
|
13 => "trixie",
|
|
28
34
|
12 => "bookworm",
|
|
@@ -34,21 +40,43 @@ module Kitchen
|
|
|
34
40
|
6 => "squeeze",
|
|
35
41
|
}.freeze
|
|
36
42
|
|
|
37
|
-
#
|
|
38
|
-
#
|
|
43
|
+
# The account EC2 creates on this platform's official AMIs.
|
|
44
|
+
#
|
|
45
|
+
# Debian uses "admin" rather than the "ec2-user" or distribution-named
|
|
46
|
+
# account most other platforms create.
|
|
47
|
+
#
|
|
48
|
+
# @return [String] the default SSH username
|
|
39
49
|
def username
|
|
40
50
|
"admin"
|
|
41
51
|
end
|
|
42
52
|
|
|
53
|
+
# The Debian release codename for the requested version.
|
|
54
|
+
#
|
|
55
|
+
# Only the major version selects a codename, so a more precise version
|
|
56
|
+
# such as "12.5" is truncated, with a warning that the extra precision
|
|
57
|
+
# is being discarded. With no version at all, the newest known release
|
|
58
|
+
# is used.
|
|
59
|
+
#
|
|
60
|
+
# @return [String, nil] the codename, or nil for an unknown version
|
|
43
61
|
def codename
|
|
44
62
|
v = version
|
|
45
|
-
|
|
63
|
+
# Warn only when truncating to the major version actually discards
|
|
64
|
+
# something. Comparing string forms keeps a version that arrived as
|
|
65
|
+
# an Integer from warning about itself.
|
|
66
|
+
if v && v.to_s != v.to_i.to_s
|
|
46
67
|
warn("WARN: Debian version #{version} specified, but searching for #{version.to_i} instead.")
|
|
47
|
-
v = v.to_i
|
|
48
68
|
end
|
|
49
69
|
v ? DEBIAN_CODENAMES[v.to_i] : DEBIAN_CODENAMES.values.first
|
|
50
70
|
end
|
|
51
71
|
|
|
72
|
+
# EC2 image filters that select Debian cloud images.
|
|
73
|
+
#
|
|
74
|
+
# A filter is added for {StandardPlatform#architecture} only when one was
|
|
75
|
+
# requested, so that an unspecified architecture matches any of them.
|
|
76
|
+
#
|
|
77
|
+
# @return [Hash{String => String, Array<String>}] filter name to the value
|
|
78
|
+
# or values it must match
|
|
79
|
+
# @see StandardPlatform#find_image
|
|
52
80
|
def image_search
|
|
53
81
|
search = {}
|
|
54
82
|
|
|
@@ -70,15 +98,26 @@ module Kitchen
|
|
|
70
98
|
search
|
|
71
99
|
end
|
|
72
100
|
|
|
101
|
+
# Detect this platform from an EC2 image.
|
|
102
|
+
#
|
|
103
|
+
# Matching is done on the image name, which is the only reliable signal
|
|
104
|
+
# EC2 exposes about what an AMI actually contains.
|
|
105
|
+
#
|
|
106
|
+
# @param driver [Kitchen::Driver::Ec2] the driver requesting detection
|
|
107
|
+
# @param image [Aws::EC2::Image] the image to inspect
|
|
108
|
+
# @return [Debian, nil] a platform when the image is Debian, otherwise nil
|
|
73
109
|
def self.from_image(driver, image)
|
|
74
110
|
return unless /debian/i.match?(image.name)
|
|
75
111
|
|
|
76
112
|
image.name =~ /\b(\d+|#{DEBIAN_CODENAMES.values.join("|")})\b/i
|
|
77
113
|
version = (Regexp.last_match || [])[1]
|
|
78
114
|
if version&.to_i&.zero?
|
|
115
|
+
# `to_s`, so that a codename-derived version is the same type as a
|
|
116
|
+
# version read straight out of the image name. Callers compare and
|
|
117
|
+
# display these without caring which path produced them.
|
|
79
118
|
version = DEBIAN_CODENAMES.find do |_v, codename|
|
|
80
119
|
codename == version.downcase
|
|
81
|
-
end
|
|
120
|
+
end&.first&.to_s
|
|
82
121
|
end
|
|
83
122
|
new(driver, "debian", version, image.architecture)
|
|
84
123
|
end
|
|
@@ -23,12 +23,23 @@ module Kitchen
|
|
|
23
23
|
class Fedora < StandardPlatform
|
|
24
24
|
StandardPlatform.platforms["fedora"] = self
|
|
25
25
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
26
|
+
# The account EC2 creates on this platform's official AMIs.
|
|
27
|
+
#
|
|
28
|
+
# Used as the SSH username when the transport does not specify one.
|
|
29
|
+
#
|
|
30
|
+
# @return [String] the default SSH username
|
|
28
31
|
def username
|
|
29
32
|
"fedora"
|
|
30
33
|
end
|
|
31
34
|
|
|
35
|
+
# EC2 image filters that select Fedora Cloud Base images.
|
|
36
|
+
#
|
|
37
|
+
# A filter is added for {StandardPlatform#architecture} only when one was
|
|
38
|
+
# requested, so that an unspecified architecture matches any of them.
|
|
39
|
+
#
|
|
40
|
+
# @return [Hash{String => String, Array<String>}] filter name to the value
|
|
41
|
+
# or values it must match
|
|
42
|
+
# @see StandardPlatform#find_image
|
|
32
43
|
def image_search
|
|
33
44
|
search = {
|
|
34
45
|
"owner-id" => "125523088429",
|
|
@@ -38,6 +49,14 @@ module Kitchen
|
|
|
38
49
|
search
|
|
39
50
|
end
|
|
40
51
|
|
|
52
|
+
# Detect this platform from an EC2 image.
|
|
53
|
+
#
|
|
54
|
+
# Matching is done on the image name, which is the only reliable signal
|
|
55
|
+
# EC2 exposes about what an AMI actually contains.
|
|
56
|
+
#
|
|
57
|
+
# @param driver [Kitchen::Driver::Ec2] the driver requesting detection
|
|
58
|
+
# @param image [Aws::EC2::Image] the image to inspect
|
|
59
|
+
# @return [Fedora, nil] a platform when the image is Fedora, otherwise nil
|
|
41
60
|
def self.from_image(driver, image)
|
|
42
61
|
return unless /fedora/i.match?(image.name)
|
|
43
62
|
|
|
@@ -23,14 +23,31 @@ module Kitchen
|
|
|
23
23
|
class Freebsd < StandardPlatform
|
|
24
24
|
StandardPlatform.platforms["freebsd"] = self
|
|
25
25
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
26
|
+
# The account EC2 creates on this platform's official AMIs.
|
|
27
|
+
#
|
|
28
|
+
# Used as the SSH username when the transport does not specify one.
|
|
29
|
+
#
|
|
30
|
+
# @return [String] the default SSH username
|
|
28
31
|
def username
|
|
29
32
|
"ec2-user"
|
|
30
33
|
end
|
|
31
34
|
|
|
35
|
+
# The command used to elevate privileges on this platform.
|
|
36
|
+
#
|
|
37
|
+
# FreeBSD AMIs do not configure sudo for the default account, so this
|
|
38
|
+
# is deliberately nil rather than the usual "sudo".
|
|
39
|
+
#
|
|
40
|
+
# @return [nil] always
|
|
32
41
|
def sudo_command; end
|
|
33
42
|
|
|
43
|
+
# EC2 image filters that select FreeBSD RELEASE images.
|
|
44
|
+
#
|
|
45
|
+
# A filter is added for {StandardPlatform#architecture} only when one was
|
|
46
|
+
# requested, so that an unspecified architecture matches any of them.
|
|
47
|
+
#
|
|
48
|
+
# @return [Hash{String => String, Array<String>}] filter name to the value
|
|
49
|
+
# or values it must match
|
|
50
|
+
# @see StandardPlatform#find_image
|
|
34
51
|
def image_search
|
|
35
52
|
search = {
|
|
36
53
|
"owner-id" => "118940168514",
|
|
@@ -40,6 +57,14 @@ module Kitchen
|
|
|
40
57
|
search
|
|
41
58
|
end
|
|
42
59
|
|
|
60
|
+
# Detect this platform from an EC2 image.
|
|
61
|
+
#
|
|
62
|
+
# Matching is done on the image name, which is the only reliable signal
|
|
63
|
+
# EC2 exposes about what an AMI actually contains.
|
|
64
|
+
#
|
|
65
|
+
# @param driver [Kitchen::Driver::Ec2] the driver requesting detection
|
|
66
|
+
# @param image [Aws::EC2::Image] the image to inspect
|
|
67
|
+
# @return [Freebsd, nil] a platform when the image is FreeBSD, otherwise nil
|
|
43
68
|
def self.from_image(driver, image)
|
|
44
69
|
return unless /freebsd/i.match?(image.name)
|
|
45
70
|
|
|
@@ -19,29 +19,55 @@ module Kitchen
|
|
|
19
19
|
module Driver
|
|
20
20
|
class Aws
|
|
21
21
|
class StandardPlatform
|
|
22
|
+
# Amazon's macOS images, which run only on dedicated Mac hosts.
|
|
23
|
+
#
|
|
24
|
+
# @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-macos-instances.html
|
|
22
25
|
class MacOS < StandardPlatform
|
|
23
26
|
StandardPlatform.platforms["macos"] = self
|
|
24
27
|
|
|
25
|
-
#
|
|
26
|
-
#
|
|
28
|
+
# The account EC2 creates on this platform's official AMIs.
|
|
29
|
+
#
|
|
30
|
+
# Used as the SSH username when the transport does not specify one.
|
|
31
|
+
#
|
|
32
|
+
# @return [String] the default SSH username
|
|
27
33
|
def username
|
|
28
34
|
"ec2-user"
|
|
29
35
|
end
|
|
30
36
|
|
|
37
|
+
# EC2 image filters that select Amazon's macOS AMIs, which run only on dedicated Mac hosts.
|
|
38
|
+
#
|
|
39
|
+
# A filter is added for {StandardPlatform#architecture} only when one was
|
|
40
|
+
# requested, so that an unspecified architecture matches any of them.
|
|
41
|
+
#
|
|
42
|
+
# @return [Hash{String => String, Array<String>}] filter name to the value
|
|
43
|
+
# or values it must match
|
|
44
|
+
# @see StandardPlatform#find_image
|
|
31
45
|
def image_search
|
|
32
46
|
search = {
|
|
33
47
|
"owner-id" => "100343932686",
|
|
34
|
-
"name" => version ? "amzn-ec2-macos-#{version}*" : "
|
|
48
|
+
"name" => version ? "amzn-ec2-macos-#{version}*" : "amzn-ec2-macos-*",
|
|
35
49
|
}
|
|
36
50
|
search["architecture"] = architecture if architecture
|
|
37
51
|
search["architecture"] = "arm64_mac" if architecture == "arm64"
|
|
38
52
|
search
|
|
39
53
|
end
|
|
40
54
|
|
|
55
|
+
# Detect this platform from an EC2 image.
|
|
56
|
+
#
|
|
57
|
+
# Matching is done on the image name, which is the only reliable signal
|
|
58
|
+
# EC2 exposes about what an AMI actually contains.
|
|
59
|
+
#
|
|
60
|
+
# @param driver [Kitchen::Driver::Ec2] the driver requesting detection
|
|
61
|
+
# @param image [Aws::EC2::Image] the image to inspect
|
|
62
|
+
# @return [MacOS, nil] a platform when the image is macOS, otherwise nil
|
|
41
63
|
def self.from_image(driver, image)
|
|
42
64
|
return unless /amzn-ec2-macos/i.match?(image.name)
|
|
43
65
|
|
|
44
|
-
|
|
66
|
+
# `(\.\d+)?`, not `(\.\d+[\.\d])?`: the character class matched the
|
|
67
|
+
# separator that follows the minor version, capturing it into the
|
|
68
|
+
# version string ("2018.03.") and failing outright when the minor
|
|
69
|
+
# version was followed by anything but a dot or digit.
|
|
70
|
+
image.name =~ /\b(\d+(\.\d+)?)/i
|
|
45
71
|
new(driver, "macos", (Regexp.last_match || [])[1], image.architecture)
|
|
46
72
|
end
|
|
47
73
|
end
|
|
@@ -24,17 +24,38 @@ module Kitchen
|
|
|
24
24
|
StandardPlatform.platforms["rhel"] = self
|
|
25
25
|
StandardPlatform.platforms["el"] = self
|
|
26
26
|
|
|
27
|
+
# Build a Red Hat Enterprise Linux platform.
|
|
28
|
+
#
|
|
29
|
+
# This class is registered under both "rhel" and "el", so the name it
|
|
30
|
+
# was constructed with is discarded and normalized to "rhel".
|
|
31
|
+
#
|
|
32
|
+
# @param driver [Kitchen::Driver::Ec2] the driver
|
|
33
|
+
# @param _name [String] the registered name, ignored
|
|
34
|
+
# @param version [String, nil] the requested version, e.g. "9.4"
|
|
35
|
+
# @param architecture [String, nil] the requested architecture
|
|
27
36
|
def initialize(driver, _name, version, architecture)
|
|
28
37
|
# rhel = el
|
|
29
38
|
super(driver, "rhel", version, architecture)
|
|
30
39
|
end
|
|
31
40
|
|
|
32
|
-
#
|
|
33
|
-
#
|
|
41
|
+
# The account EC2 creates on this platform's official AMIs.
|
|
42
|
+
#
|
|
43
|
+
# RHEL only gained the unprivileged "ec2-user" account in 6.4; earlier
|
|
44
|
+
# releases are logged into as root.
|
|
45
|
+
#
|
|
46
|
+
# @return [String] the default SSH username
|
|
34
47
|
def username
|
|
35
48
|
version && version.to_f < 6.4 ? "root" : "ec2-user"
|
|
36
49
|
end
|
|
37
50
|
|
|
51
|
+
# EC2 image filters that select Red Hat Enterprise Linux AMIs published by Red Hat.
|
|
52
|
+
#
|
|
53
|
+
# A filter is added for {StandardPlatform#architecture} only when one was
|
|
54
|
+
# requested, so that an unspecified architecture matches any of them.
|
|
55
|
+
#
|
|
56
|
+
# @return [Hash{String => String, Array<String>}] filter name to the value
|
|
57
|
+
# or values it must match
|
|
58
|
+
# @see StandardPlatform#find_image
|
|
38
59
|
def image_search
|
|
39
60
|
search = {
|
|
40
61
|
"owner-id" => "309956199498",
|
|
@@ -44,6 +65,14 @@ module Kitchen
|
|
|
44
65
|
search
|
|
45
66
|
end
|
|
46
67
|
|
|
68
|
+
# Detect this platform from an EC2 image.
|
|
69
|
+
#
|
|
70
|
+
# Matching is done on the image name, which is the only reliable signal
|
|
71
|
+
# EC2 exposes about what an AMI actually contains.
|
|
72
|
+
#
|
|
73
|
+
# @param driver [Kitchen::Driver::Ec2] the driver requesting detection
|
|
74
|
+
# @param image [Aws::EC2::Image] the image to inspect
|
|
75
|
+
# @return [El, nil] a platform when the image is Red Hat Enterprise Linux, otherwise nil
|
|
47
76
|
def self.from_image(driver, image)
|
|
48
77
|
return unless /rhel/i.match?(image.name)
|
|
49
78
|
|
|
@@ -51,6 +80,15 @@ module Kitchen
|
|
|
51
80
|
new(driver, "rhel", (Regexp.last_match || [])[1], image.architecture)
|
|
52
81
|
end
|
|
53
82
|
|
|
83
|
+
# Sort images newest release first, preferring generally available
|
|
84
|
+
# releases over betas.
|
|
85
|
+
#
|
|
86
|
+
# A Beta AMI carries a higher version number than the current GA
|
|
87
|
+
# release, so a plain version sort would select it. Betas are pushed
|
|
88
|
+
# to the back after sorting.
|
|
89
|
+
#
|
|
90
|
+
# @param images [Array<Aws::EC2::Image>] the images to sort
|
|
91
|
+
# @return [Array<Aws::EC2::Image>] the images, best match first
|
|
54
92
|
def sort_by_version(images)
|
|
55
93
|
# First do a normal version sort
|
|
56
94
|
super(images)
|
|
@@ -19,16 +19,31 @@ module Kitchen
|
|
|
19
19
|
module Driver
|
|
20
20
|
class Aws
|
|
21
21
|
class StandardPlatform
|
|
22
|
+
# Rocky Linux images published by the Rocky Enterprise Software
|
|
23
|
+
# Foundation.
|
|
24
|
+
#
|
|
25
|
+
# @see https://rockylinux.org/cloud-images
|
|
22
26
|
class Rocky < StandardPlatform
|
|
23
27
|
StandardPlatform.platforms["rocky"] = self
|
|
24
28
|
StandardPlatform.platforms["rockylinux"] = self
|
|
25
29
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
30
|
+
# The account EC2 creates on this platform's official AMIs.
|
|
31
|
+
#
|
|
32
|
+
# Used as the SSH username when the transport does not specify one.
|
|
33
|
+
#
|
|
34
|
+
# @return [String] the default SSH username
|
|
28
35
|
def username
|
|
29
36
|
"rocky"
|
|
30
37
|
end
|
|
31
38
|
|
|
39
|
+
# EC2 image filters that select Rocky Linux images published by the Rocky project.
|
|
40
|
+
#
|
|
41
|
+
# A filter is added for {StandardPlatform#architecture} only when one was
|
|
42
|
+
# requested, so that an unspecified architecture matches any of them.
|
|
43
|
+
#
|
|
44
|
+
# @return [Hash{String => String, Array<String>}] filter name to the value
|
|
45
|
+
# or values it must match
|
|
46
|
+
# @see StandardPlatform#find_image
|
|
32
47
|
def image_search
|
|
33
48
|
search = {
|
|
34
49
|
"owner-id" => "792107900819",
|
|
@@ -38,10 +53,22 @@ module Kitchen
|
|
|
38
53
|
search
|
|
39
54
|
end
|
|
40
55
|
|
|
56
|
+
# Detect this platform from an EC2 image.
|
|
57
|
+
#
|
|
58
|
+
# Matching is done on the image name, which is the only reliable signal
|
|
59
|
+
# EC2 exposes about what an AMI actually contains.
|
|
60
|
+
#
|
|
61
|
+
# @param driver [Kitchen::Driver::Ec2] the driver requesting detection
|
|
62
|
+
# @param image [Aws::EC2::Image] the image to inspect
|
|
63
|
+
# @return [Rocky, nil] a platform when the image is Rocky Linux, otherwise nil
|
|
41
64
|
def self.from_image(driver, image)
|
|
42
65
|
return unless /Rocky-/i.match?(image.name)
|
|
43
66
|
|
|
44
|
-
|
|
67
|
+
# `(\.\d+)?`, not `(\.\d+[\.\d])?`: the character class matched the
|
|
68
|
+
# separator that follows the minor version, capturing it into the
|
|
69
|
+
# version string ("2018.03.") and failing outright when the minor
|
|
70
|
+
# version was followed by anything but a dot or digit.
|
|
71
|
+
image.name =~ /\b(\d+(\.\d+)?)/i
|
|
45
72
|
new(driver, "rocky", (Regexp.last_match || [])[1], image.architecture)
|
|
46
73
|
end
|
|
47
74
|
end
|
|
@@ -23,12 +23,23 @@ module Kitchen
|
|
|
23
23
|
class Ubuntu < StandardPlatform
|
|
24
24
|
StandardPlatform.platforms["ubuntu"] = self
|
|
25
25
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
26
|
+
# The account EC2 creates on this platform's official AMIs.
|
|
27
|
+
#
|
|
28
|
+
# Used as the SSH username when the transport does not specify one.
|
|
29
|
+
#
|
|
30
|
+
# @return [String] the default SSH username
|
|
28
31
|
def username
|
|
29
32
|
"ubuntu"
|
|
30
33
|
end
|
|
31
34
|
|
|
35
|
+
# EC2 image filters that select Ubuntu cloud images published by Canonical.
|
|
36
|
+
#
|
|
37
|
+
# A filter is added for {StandardPlatform#architecture} only when one was
|
|
38
|
+
# requested, so that an unspecified architecture matches any of them.
|
|
39
|
+
#
|
|
40
|
+
# @return [Hash{String => String, Array<String>}] filter name to the value
|
|
41
|
+
# or values it must match
|
|
42
|
+
# @see StandardPlatform#find_image
|
|
32
43
|
def image_search
|
|
33
44
|
search = {
|
|
34
45
|
"owner-id" => "099720109477",
|
|
@@ -38,6 +49,14 @@ module Kitchen
|
|
|
38
49
|
search
|
|
39
50
|
end
|
|
40
51
|
|
|
52
|
+
# Detect this platform from an EC2 image.
|
|
53
|
+
#
|
|
54
|
+
# Matching is done on the image name, which is the only reliable signal
|
|
55
|
+
# EC2 exposes about what an AMI actually contains.
|
|
56
|
+
#
|
|
57
|
+
# @param driver [Kitchen::Driver::Ec2] the driver requesting detection
|
|
58
|
+
# @param image [Aws::EC2::Image] the image to inspect
|
|
59
|
+
# @return [Ubuntu, nil] a platform when the image is Ubuntu, otherwise nil
|
|
41
60
|
def self.from_image(driver, image)
|
|
42
61
|
return unless /ubuntu/i.match?(image.name)
|
|
43
62
|
|
|
@@ -23,34 +23,39 @@ module Kitchen
|
|
|
23
23
|
class Windows < StandardPlatform
|
|
24
24
|
StandardPlatform.platforms["windows"] = self
|
|
25
25
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
26
|
+
# The account EC2 creates on this platform's official AMIs.
|
|
27
|
+
#
|
|
28
|
+
# Used as the SSH username when the transport does not specify one.
|
|
29
|
+
#
|
|
30
|
+
# @return [String] the default SSH username
|
|
28
31
|
def username
|
|
29
32
|
"administrator"
|
|
30
33
|
end
|
|
31
34
|
|
|
32
|
-
#
|
|
35
|
+
# EC2 image filters that select Amazon's Windows Server AMIs.
|
|
36
|
+
#
|
|
37
|
+
# Windows AMI names encode the release, an optional revision ("R2")
|
|
38
|
+
# and an optional service pack, and the naming scheme changed with
|
|
39
|
+
# Server 2016. The requested version is decomposed by
|
|
40
|
+
# {#windows_version_parts} and turned into whichever set of name
|
|
41
|
+
# patterns can match it:
|
|
42
|
+
#
|
|
43
|
+
# "windows" Windows_Server-*-RTM-, -SP*-, -R*_RTM-,
|
|
44
|
+
# -R*_SP*-, and Windows_Server-*-Full-Base-*
|
|
45
|
+
# "windows-2012" Windows_Server-2012-RTM-, -2012-SP*-
|
|
46
|
+
# "windows-2012r2" Windows_Server-2012-R2_RTM-, -R2_SP*-
|
|
47
|
+
# "windows-2012sp1" Windows_Server-2012-SP1-
|
|
48
|
+
# "windows-2012r2sp1" Windows_Server-2012-R2_SP1-
|
|
49
|
+
# "windows-2016" Windows_Server-2016-English-Full-Base-*
|
|
50
|
+
# "windows-2019" Windows_Server-2019-English-Full-Base-*
|
|
33
51
|
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
# Windows_Server-2012-R2_RTM-, Windows_Server-2012-R2_SP*-
|
|
42
|
-
# "windows-2012sp1" -> [2012, 0, 1]
|
|
43
|
-
# Windows_Server-2012-SP1-
|
|
44
|
-
# "windows-2012rtm" -> [2012, 0, 0]
|
|
45
|
-
# Windows_Server-2012-RTM-
|
|
46
|
-
# "windows-2012r2sp1" -> [2012, 2, 1]
|
|
47
|
-
# Windows_Server-2012-R2_SP1-
|
|
48
|
-
# "windows-2012r2rtm" -> [2012, 2, 0]
|
|
49
|
-
# Windows_Server-2012-R2_RTM-
|
|
50
|
-
# "windows-2016" -> [2016, 0, nil]
|
|
51
|
-
# Windows_Server-2016-
|
|
52
|
-
# "windows-2019" -> [2019, 0, nil]
|
|
53
|
-
# Windows_Server-2019-
|
|
52
|
+
# A filter is added for {StandardPlatform#architecture} only when one
|
|
53
|
+
# was requested, so that an unspecified architecture matches any.
|
|
54
|
+
#
|
|
55
|
+
# @return [Hash{String => String, Array<String>}] filter name to the
|
|
56
|
+
# value or values it must match
|
|
57
|
+
# @see #windows_name_filter
|
|
58
|
+
# @see StandardPlatform#find_image
|
|
54
59
|
def image_search
|
|
55
60
|
search = {
|
|
56
61
|
"owner-alias" => "amazon",
|
|
@@ -60,6 +65,15 @@ module Kitchen
|
|
|
60
65
|
search
|
|
61
66
|
end
|
|
62
67
|
|
|
68
|
+
# Sort images newest release first.
|
|
69
|
+
#
|
|
70
|
+
# Windows versions cannot be compared as numbers -- "2012r2" is newer
|
|
71
|
+
# than "2012" but older than "2016" -- so each image is reduced to a
|
|
72
|
+
# [major, revision, service_pack] tuple and those are compared
|
|
73
|
+
# instead.
|
|
74
|
+
#
|
|
75
|
+
# @param images [Array<Aws::EC2::Image>] the images to sort
|
|
76
|
+
# @return [Array<Aws::EC2::Image>] the images, newest release first
|
|
63
77
|
def sort_by_version(images)
|
|
64
78
|
# 2008r2rtm -> [ img1, img2, img3 ]
|
|
65
79
|
# 2012r2sp1 -> [ img4, img5 ]
|
|
@@ -69,6 +83,14 @@ module Kitchen
|
|
|
69
83
|
.reverse.flat_map { |_version, platform_images| platform_images }
|
|
70
84
|
end
|
|
71
85
|
|
|
86
|
+
# Detect this platform from an EC2 image.
|
|
87
|
+
#
|
|
88
|
+
# Matching is done on the image name, which is the only reliable signal
|
|
89
|
+
# EC2 exposes about what an AMI actually contains.
|
|
90
|
+
#
|
|
91
|
+
# @param driver [Kitchen::Driver::Ec2] the driver requesting detection
|
|
92
|
+
# @param image [Aws::EC2::Image] the image to inspect
|
|
93
|
+
# @return [Windows, nil] a platform when the image is Windows Server, otherwise nil
|
|
72
94
|
def self.from_image(driver, image)
|
|
73
95
|
return unless /Windows/i.match?(image.name)
|
|
74
96
|
|
|
@@ -88,18 +110,25 @@ module Kitchen
|
|
|
88
110
|
|
|
89
111
|
protected
|
|
90
112
|
|
|
91
|
-
#
|
|
113
|
+
# Decompose a Windows version string into comparable parts.
|
|
114
|
+
#
|
|
115
|
+
# A missing revision becomes 0 so that "2012" and "2012r2" order
|
|
116
|
+
# correctly against each other. A missing service pack stays nil,
|
|
117
|
+
# which means "any", while an explicit "rtm" becomes 0.
|
|
92
118
|
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
#
|
|
119
|
+
# nil -> [nil, nil, nil]
|
|
120
|
+
# "2012" -> [2012, 0, nil]
|
|
121
|
+
# "2012r2" -> [2012, 2, nil]
|
|
122
|
+
# "2012rtm" -> [2012, 0, 0]
|
|
123
|
+
# "2012sp4" -> [2012, 0, 4]
|
|
124
|
+
# "2012r2sp4"-> [2012, 2, 4]
|
|
125
|
+
# "2016" -> [2016, 0, nil]
|
|
126
|
+
#
|
|
127
|
+
# A leading "server-" is stripped first, so that a platform named
|
|
128
|
+
# "windows-server-2019" behaves like "windows-2019".
|
|
129
|
+
#
|
|
130
|
+
# @return [Array(Integer, Integer, Integer), Array(nil, nil, nil)]
|
|
131
|
+
# the major version, revision and service pack
|
|
103
132
|
def windows_version_parts
|
|
104
133
|
version = self.version
|
|
105
134
|
if version
|
|
@@ -131,6 +160,10 @@ module Kitchen
|
|
|
131
160
|
|
|
132
161
|
private
|
|
133
162
|
|
|
163
|
+
# Build the AMI name patterns for the requested version.
|
|
164
|
+
#
|
|
165
|
+
# @return [String, Array<String>] a single pattern for releases with a
|
|
166
|
+
# predictable name, otherwise every pattern that could match
|
|
134
167
|
def windows_name_filter
|
|
135
168
|
major, revision, service_pack = windows_version_parts
|
|
136
169
|
if [2025, 2022, 2019, 2016].include?(major)
|
|
@@ -99,7 +99,13 @@ module Kitchen
|
|
|
99
99
|
#
|
|
100
100
|
# Find the best matching image for the given image search.
|
|
101
101
|
#
|
|
102
|
-
#
|
|
102
|
+
# The search hash is converted into EC2's filter format, and the results
|
|
103
|
+
# are ranked by {#sort_images} before the best match is taken.
|
|
104
|
+
#
|
|
105
|
+
# @param image_search [Hash{String => String, Array<String>}] EC2 image
|
|
106
|
+
# filters, keyed by filter name
|
|
107
|
+
# @return [String, nil] the image ID (e.g. "ami-213984723"), or nil when
|
|
108
|
+
# the search matched nothing
|
|
103
109
|
def find_image(image_search)
|
|
104
110
|
driver.debug("Searching for images matching #{image_search} ...")
|
|
105
111
|
# Convert to ec2 search format (pairs of name+values)
|
|
@@ -120,12 +126,18 @@ module Kitchen
|
|
|
120
126
|
# The list of StandardPlatform objects. StandardPlatforms register
|
|
121
127
|
# themselves with this.
|
|
122
128
|
#
|
|
123
|
-
# @return Array
|
|
129
|
+
# @return [Array<Kitchen::Driver::Aws::StandardPlatform>]
|
|
124
130
|
#
|
|
125
131
|
def self.platforms
|
|
126
132
|
@platforms ||= {}
|
|
127
133
|
end
|
|
128
134
|
|
|
135
|
+
# A human-readable description of this platform.
|
|
136
|
+
#
|
|
137
|
+
# Version and architecture are omitted when unknown, so an unqualified
|
|
138
|
+
# platform reads as just "ubuntu" rather than "ubuntu ".
|
|
139
|
+
#
|
|
140
|
+
# @return [String] e.g. "ubuntu 24.04 x86_64"
|
|
129
141
|
def to_s
|
|
130
142
|
"#{name}#{version ? " #{version}" : ""}#{architecture ? " #{architecture}" : ""}"
|
|
131
143
|
end
|
|
@@ -162,6 +174,16 @@ module Kitchen
|
|
|
162
174
|
nil
|
|
163
175
|
end
|
|
164
176
|
|
|
177
|
+
# Split a platform string into its parts.
|
|
178
|
+
#
|
|
179
|
+
# The trailing segment is only treated as an architecture when it is one
|
|
180
|
+
# of {SUPPORTED_ARCHITECTURES}; anything else stays part of the version,
|
|
181
|
+
# so that a typo surfaces as an unmatched version rather than being
|
|
182
|
+
# silently discarded.
|
|
183
|
+
#
|
|
184
|
+
# @param platform_string [String] e.g. "centos-9-x86_64"
|
|
185
|
+
# @return [Array(String, String, String)] the platform name, version and
|
|
186
|
+
# architecture, any of which except the name may be nil
|
|
165
187
|
def self.parse_platform_string(platform_string)
|
|
166
188
|
platform, version = platform_string.split("-", 2)
|
|
167
189
|
|
|
@@ -203,6 +225,16 @@ module Kitchen
|
|
|
203
225
|
|
|
204
226
|
# Not supported yet: aix mac_os_x nexus solaris
|
|
205
227
|
|
|
228
|
+
# Move images matching a predicate ahead of those that do not.
|
|
229
|
+
#
|
|
230
|
+
# This is a stable partition rather than a sort, so it expresses a
|
|
231
|
+
# preference without disturbing the ordering established by earlier
|
|
232
|
+
# preferences.
|
|
233
|
+
#
|
|
234
|
+
# @param images [Array<Aws::EC2::Image>] the images to reorder
|
|
235
|
+
# @yieldparam image [Aws::EC2::Image] an image to test
|
|
236
|
+
# @yieldreturn [Boolean] true when the image is preferred
|
|
237
|
+
# @return [Array<Aws::EC2::Image>] preferred images first
|
|
206
238
|
def prefer(images, &block)
|
|
207
239
|
# Put the matching ones *before* the non-matching ones.
|
|
208
240
|
matching, non_matching = images.partition(&block)
|
|
@@ -211,6 +243,14 @@ module Kitchen
|
|
|
211
243
|
|
|
212
244
|
private
|
|
213
245
|
|
|
246
|
+
# Rank candidate images, best match first.
|
|
247
|
+
#
|
|
248
|
+
# Preferences are applied from weakest to strongest, each one a stable
|
|
249
|
+
# partition, so the last applied wins: version beats virtualization
|
|
250
|
+
# type, which beats root device type, and so on down to creation date.
|
|
251
|
+
#
|
|
252
|
+
# @param images [Array<Aws::EC2::Image>] the images to rank
|
|
253
|
+
# @return [Array<Aws::EC2::Image>] the images, best match first
|
|
214
254
|
def sort_images(images)
|
|
215
255
|
# P6: We prefer more recent images over older ones
|
|
216
256
|
images = images.sort_by(&:creation_date).reverse
|
|
@@ -230,6 +270,10 @@ module Kitchen
|
|
|
230
270
|
sort_by_version(images)
|
|
231
271
|
end
|
|
232
272
|
|
|
273
|
+
# Log the search results, with the platform detected for each image.
|
|
274
|
+
#
|
|
275
|
+
# @param images [Array<Aws::EC2::Image>] the images the search returned
|
|
276
|
+
# @return [void]
|
|
233
277
|
def show_returned_images(images)
|
|
234
278
|
if images.empty?
|
|
235
279
|
driver.error("Search returned 0 images.")
|