kitchen-google 3.0.0 → 3.0.2
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/gce.rb +115 -16
- data/lib/kitchen/driver/gce_version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7bb68767fd70358c97f209575379ad984b9aab4fd4b3f0377cf1e77b5167796a
|
|
4
|
+
data.tar.gz: 83f5317efdf99856679a51a88a95c5d5601dc220989285c54e5771b290b90393
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 59c12a1a8494f2c99df3a5ddb5b68bcb34fde00815e3ed25df084b4e1cb7b96057f030486350870b694ac2cd827fdffc47f94a421c7586118d9338dc7c5870e7
|
|
7
|
+
data.tar.gz: 5e1f05a0b84feab76831418aeff5b5900d84a8285fbe3bf0b7b9c046ec958e9e6d46027bb47e493842c3e84f91d2398f094f23058b6f97b82be23a06b86e36bd
|
data/lib/kitchen/driver/gce.rb
CHANGED
|
@@ -89,7 +89,10 @@ module Kitchen
|
|
|
89
89
|
default_config :tags, []
|
|
90
90
|
default_config :preemptible, false
|
|
91
91
|
default_config :auto_restart, false
|
|
92
|
-
|
|
92
|
+
# Matches GCE's own default for onHostMaintenance. Several machine
|
|
93
|
+
# families, E2 among them, reject TERMINATE unless the instance is
|
|
94
|
+
# preemptible, so defaulting this off makes them unusable.
|
|
95
|
+
default_config :auto_migrate, true
|
|
93
96
|
default_config :image_family, nil
|
|
94
97
|
default_config :image_name, nil
|
|
95
98
|
default_config :image_project, nil
|
|
@@ -125,13 +128,35 @@ module Kitchen
|
|
|
125
128
|
|
|
126
129
|
# Configuration applied to every disk before the user's own settings.
|
|
127
130
|
#
|
|
131
|
+
# Deliberately sets no `disk_type`. GCE derives an omitted disk type from
|
|
132
|
+
# the instance's machine series -- pd-standard on first- and
|
|
133
|
+
# second-generation series such as N1 and N2, pd-balanced on C3, C3D and
|
|
134
|
+
# M3, and hyperdisk-balanced on C4, N4 and newer -- so leaving it unset is
|
|
135
|
+
# the only default that is compatible with every machine type. Naming one
|
|
136
|
+
# here would fail outright on the families that no longer accept it.
|
|
137
|
+
#
|
|
128
138
|
# @return [Hash] the per-disk defaults
|
|
129
139
|
DISK_DEFAULT_CONFIG = {
|
|
130
140
|
autodelete_disk: true,
|
|
131
141
|
disk_size: 10,
|
|
132
|
-
disk_type: "pd-standard",
|
|
133
142
|
}.freeze
|
|
134
143
|
|
|
144
|
+
# Local Windows account Test Kitchen's WinRM transport defaults to, and
|
|
145
|
+
# which Google's Windows images ship disabled.
|
|
146
|
+
#
|
|
147
|
+
# @return [String] the built-in administrator account name
|
|
148
|
+
BUILTIN_ADMINISTRATOR = "administrator".freeze
|
|
149
|
+
|
|
150
|
+
# Told to the user when they are about to wait out a WinRM timeout for a
|
|
151
|
+
# reason the driver can see coming.
|
|
152
|
+
#
|
|
153
|
+
# @return [String] the warning text
|
|
154
|
+
BUILTIN_ADMINISTRATOR_WARNING =
|
|
155
|
+
"The WinRM transport is connecting as the built-in Administrator account, which is " \
|
|
156
|
+
"disabled on Google's Windows images. The guest agent resets its password without " \
|
|
157
|
+
"enabling it, so the login will be refused. Set transport.username to any other name " \
|
|
158
|
+
"and the agent will create that account instead.".freeze
|
|
159
|
+
|
|
135
160
|
# Human-readable driver name shown in Test Kitchen output.
|
|
136
161
|
#
|
|
137
162
|
# @return [String] the driver's display name
|
|
@@ -164,13 +189,17 @@ module Kitchen
|
|
|
164
189
|
info("Creating GCE instance <#{server_name}> in project #{project}, zone #{zone}...")
|
|
165
190
|
operation = connection.insert_instance(project, zone, create_instance_object(server_name))
|
|
166
191
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
192
|
+
# GCE starts billing for the instance as soon as the insert is
|
|
193
|
+
# accepted, so record it before waiting on the operation. Anything that
|
|
194
|
+
# goes wrong from here on can then be torn down by the rescue below,
|
|
195
|
+
# and by `kitchen destroy` if the process does not survive to run it.
|
|
170
196
|
state[:server_name] = server_name
|
|
171
|
-
state[:hostname] = ip_address_for(server)
|
|
172
197
|
state[:zone] = zone
|
|
173
198
|
|
|
199
|
+
wait_for_operation(operation)
|
|
200
|
+
|
|
201
|
+
state[:hostname] = ip_address_for(server_instance(server_name))
|
|
202
|
+
|
|
174
203
|
info("Server <#{server_name}> created.")
|
|
175
204
|
|
|
176
205
|
update_windows_password(server_name)
|
|
@@ -269,9 +298,12 @@ module Kitchen
|
|
|
269
298
|
boot: true,
|
|
270
299
|
autodelete_disk: config.fetch(:autodelete_disk, DISK_DEFAULT_CONFIG[:autodelete_disk]),
|
|
271
300
|
disk_size: config.fetch(:disk_size, DISK_DEFAULT_CONFIG[:disk_size]),
|
|
272
|
-
disk_type: config.fetch(:disk_type, DISK_DEFAULT_CONFIG[:disk_type]),
|
|
273
301
|
}
|
|
274
302
|
|
|
303
|
+
# Carry the key only when the user set it, so that an unset type stays
|
|
304
|
+
# absent rather than becoming an explicit nil. See DISK_DEFAULT_CONFIG.
|
|
305
|
+
disk_config[:disk_type] = config[:disk_type] if config[:disk_type]
|
|
306
|
+
|
|
275
307
|
raise "Disk type #{disk_config[:disk_type]} is not valid" unless valid_disk_type?(disk_config[:disk_type])
|
|
276
308
|
|
|
277
309
|
disk_config
|
|
@@ -388,11 +420,13 @@ module Kitchen
|
|
|
388
420
|
raise "You cannot use autodelete_disk, disk_size or disk_type with the new disks configuration" if old_disk_configuration_present? && new_disk_configuration_present?
|
|
389
421
|
raise "Disk image #{config[:image_name]} is not valid - check your image name and image project" if boot_disk_source_image.nil?
|
|
390
422
|
|
|
423
|
+
warn(BUILTIN_ADMINISTRATOR_WARNING) if winrm_transport? && builtin_administrator?
|
|
391
424
|
warn("Both zone and region specified - region will be ignored.") if config[:zone] && config[:region]
|
|
392
425
|
warn("Both image family and name specified - image family will be ignored") if config[:image_family] && config[:image_name]
|
|
393
426
|
warn("Image project not specified - searching current project only") unless config[:image_project]
|
|
394
427
|
warn("Subnet project not specified - searching current project only") if config[:subnet] && !config[:subnet_project]
|
|
395
428
|
warn("Auto-migrate disabled for preemptible instance") if preemptible? && config[:auto_migrate]
|
|
429
|
+
warn("Auto-migrate disabled for instance with guest accelerators") if guest_accelerators? && config[:auto_migrate]
|
|
396
430
|
warn("Auto-restart disabled for preemptible instance") if preemptible? && config[:auto_restart]
|
|
397
431
|
warn("These configs are deprecated - consider using new disks configuration") if old_disk_configuration_present?
|
|
398
432
|
end
|
|
@@ -425,6 +459,14 @@ module Kitchen
|
|
|
425
459
|
)
|
|
426
460
|
end
|
|
427
461
|
|
|
462
|
+
# Whether the WinRM transport is configured to log in as the built-in
|
|
463
|
+
# Administrator account.
|
|
464
|
+
#
|
|
465
|
+
# @return [Boolean] true if the transport username is `administrator`
|
|
466
|
+
def builtin_administrator?
|
|
467
|
+
instance.transport[:username].to_s.casecmp?(BUILTIN_ADMINISTRATOR)
|
|
468
|
+
end
|
|
469
|
+
|
|
428
470
|
# Whether the suite's transport is WinRM, implying a Windows guest.
|
|
429
471
|
#
|
|
430
472
|
# @return [Boolean] true when the transport is WinRM
|
|
@@ -525,10 +567,13 @@ module Kitchen
|
|
|
525
567
|
|
|
526
568
|
# Whether a disk type exists in the target zone.
|
|
527
569
|
#
|
|
570
|
+
# An unset type is valid: the driver sends no `diskType` at all and GCE
|
|
571
|
+
# substitutes the default for the instance's machine series.
|
|
572
|
+
#
|
|
528
573
|
# @param disk_type [String, nil] the disk type to check
|
|
529
|
-
# @return [Boolean] true if the disk type is valid
|
|
574
|
+
# @return [Boolean] true if the disk type is valid or unset
|
|
530
575
|
def valid_disk_type?(disk_type)
|
|
531
|
-
return
|
|
576
|
+
return true if disk_type.nil?
|
|
532
577
|
|
|
533
578
|
check_api_call { connection.get_disk_type(project, zone, disk_type) }
|
|
534
579
|
end
|
|
@@ -753,17 +798,19 @@ module Kitchen
|
|
|
753
798
|
disk.boot = true if disk_config[:boot]
|
|
754
799
|
disk.auto_delete = disk_config[:autodelete_disk]
|
|
755
800
|
params.disk_size_gb = disk_config[:disk_size]
|
|
756
|
-
params.disk_type = disk_type_url_for(disk_config[:disk_type])
|
|
801
|
+
params.disk_type = disk_type_url_for(disk_config[:disk_type]) if disk_config[:disk_type]
|
|
757
802
|
|
|
758
803
|
if local_ssd?(disk_config)
|
|
759
804
|
info("Creating a #{LOCAL_SSD_SIZE_GB} GB local ssd as scratch disk (https://cloud.google.com/compute/docs/disks/#localssds).")
|
|
760
805
|
disk.type = "SCRATCH"
|
|
761
806
|
elsif disk.boot
|
|
762
|
-
|
|
807
|
+
params.disk_size_gb = disk_size_for_image(disk_config[:disk_size], image_name)
|
|
808
|
+
info("Creating a #{params.disk_size_gb} GB boot disk named #{unique_disk_name} from image #{image_name}...")
|
|
763
809
|
params.source_image = boot_disk_source_image
|
|
764
810
|
params.disk_name = unique_disk_name
|
|
765
811
|
else
|
|
766
|
-
|
|
812
|
+
params.disk_size_gb = disk_size_for_image(disk_config[:disk_size], disk_config[:custom_image])
|
|
813
|
+
info("Creating a #{params.disk_size_gb} GB extra disk named #{unique_disk_name} from image #{disk_config[:custom_image]}...")
|
|
767
814
|
params.source_image = image_url(disk_config[:custom_image])
|
|
768
815
|
params.disk_name = unique_disk_name
|
|
769
816
|
end
|
|
@@ -771,6 +818,50 @@ module Kitchen
|
|
|
771
818
|
disk
|
|
772
819
|
end
|
|
773
820
|
|
|
821
|
+
# The size to request for a disk cloned from an image.
|
|
822
|
+
#
|
|
823
|
+
# GCE refuses to create a disk smaller than the image it is cloned from,
|
|
824
|
+
# and the driver's own 10 GB default is smaller than many stock images -
|
|
825
|
+
# every Windows image is 50 GB, and Rocky and CentOS are 20 GB. Rather
|
|
826
|
+
# than fail the run over a size the user never chose, raise the request
|
|
827
|
+
# to what the image needs and say so.
|
|
828
|
+
#
|
|
829
|
+
# @param requested [Integer, nil] the configured size in gigabytes
|
|
830
|
+
# @param image [String, nil] the image the disk is cloned from
|
|
831
|
+
# @return [Integer, nil] the size to request
|
|
832
|
+
# @api private
|
|
833
|
+
def disk_size_for_image(requested, image)
|
|
834
|
+
image_size = image_disk_size_gb(image)
|
|
835
|
+
return requested if image_size.nil? || (!requested.nil? && requested >= image_size)
|
|
836
|
+
|
|
837
|
+
warn("Requested disk size of #{requested} GB is smaller than image #{image} " \
|
|
838
|
+
"(#{image_size} GB) - creating a #{image_size} GB disk instead.")
|
|
839
|
+
image_size
|
|
840
|
+
end
|
|
841
|
+
|
|
842
|
+
# The size, in gigabytes, of an image in the image project.
|
|
843
|
+
#
|
|
844
|
+
# Memoised per image name, since the boot image is looked up more than
|
|
845
|
+
# once during a single action.
|
|
846
|
+
#
|
|
847
|
+
# @param image [String, nil] the image name
|
|
848
|
+
# @return [Integer, nil] the image's size, or nil if it cannot be read
|
|
849
|
+
# @api private
|
|
850
|
+
def image_disk_size_gb(image)
|
|
851
|
+
return if image.nil?
|
|
852
|
+
|
|
853
|
+
@image_disk_sizes ||= {}
|
|
854
|
+
return @image_disk_sizes[image] if @image_disk_sizes.key?(image)
|
|
855
|
+
|
|
856
|
+
@image_disk_sizes[image] =
|
|
857
|
+
begin
|
|
858
|
+
connection.get_image(image_project, image).disk_size_gb
|
|
859
|
+
rescue Google::Apis::ClientError => e
|
|
860
|
+
debug("Unable to read the size of image #{image}: #{e.message}")
|
|
861
|
+
nil
|
|
862
|
+
end
|
|
863
|
+
end
|
|
864
|
+
|
|
774
865
|
# Creates a standalone persistent disk, waits for it to become ready, and
|
|
775
866
|
# returns a reference attaching it to the instance.
|
|
776
867
|
#
|
|
@@ -781,7 +872,7 @@ module Kitchen
|
|
|
781
872
|
disk = Google::Apis::ComputeV1::Disk.new
|
|
782
873
|
disk.name = unique_disk_name
|
|
783
874
|
disk.size_gb = disk_config[:disk_size]
|
|
784
|
-
disk.type = disk_type_url_for(disk_config[:disk_type])
|
|
875
|
+
disk.type = disk_type_url_for(disk_config[:disk_type]) if disk_config[:disk_type]
|
|
785
876
|
|
|
786
877
|
info("Creating a #{disk_config[:disk_size]} GB disk named #{unique_disk_name}...")
|
|
787
878
|
wait_for_operation(connection.insert_disk(project, zone, disk))
|
|
@@ -1019,16 +1110,24 @@ module Kitchen
|
|
|
1019
1110
|
config[:preemptible] ? true : false
|
|
1020
1111
|
end
|
|
1021
1112
|
|
|
1022
|
-
# Whether the instance may live-migrate. Always false
|
|
1023
|
-
#
|
|
1113
|
+
# Whether the instance may live-migrate. Always false for preemptible
|
|
1114
|
+
# instances and for instances with guest accelerators attached, neither
|
|
1115
|
+
# of which GCE will migrate.
|
|
1024
1116
|
#
|
|
1025
1117
|
# @return [Boolean] true if live migration is enabled
|
|
1026
1118
|
def auto_migrate?
|
|
1027
|
-
return false if preemptible?
|
|
1119
|
+
return false if preemptible? || guest_accelerators?
|
|
1028
1120
|
|
|
1029
1121
|
config[:auto_migrate] ? true : false
|
|
1030
1122
|
end
|
|
1031
1123
|
|
|
1124
|
+
# Whether any guest accelerators are attached.
|
|
1125
|
+
#
|
|
1126
|
+
# @return [Boolean] true if the instance has at least one accelerator
|
|
1127
|
+
def guest_accelerators?
|
|
1128
|
+
!Array(config[:guest_accelerators]).empty?
|
|
1129
|
+
end
|
|
1130
|
+
|
|
1032
1131
|
# Whether the instance should restart automatically. Always false when
|
|
1033
1132
|
# preemptible, which GCE does not allow to auto-restart.
|
|
1034
1133
|
#
|