knife-windows 1.9.6 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/chef/knife/bootstrap_windows_base.rb +1 -259
- data/lib/chef/knife/bootstrap_windows_ssh.rb +10 -29
- data/lib/chef/knife/bootstrap_windows_winrm.rb +10 -56
- data/lib/chef/knife/windows_helper.rb +0 -1
- data/lib/knife-windows/version.rb +1 -1
- data/spec/assets/{win_template_rendered_with_bootstrap_install_command_on_12_5_client.txt → win_template_rendered_with_bootstrap_install_command_on_13_client.txt} +0 -0
- data/spec/spec_helper.rb +1 -27
- metadata +20 -26
- data/CHANGELOG.md +0 -176
- data/Gemfile +0 -13
- data/README.md +0 -431
- data/Rakefile +0 -21
- data/ci.gemfile +0 -16
- data/knife-windows.gemspec +0 -26
- data/lib/chef/knife/bootstrap/windows-chef-client-msi.erb +0 -259
- data/lib/chef/knife/core/windows_bootstrap_context.rb +0 -417
- data/lib/knife-windows/path_helper.rb +0 -242
- data/spec/functional/bootstrap_download_spec.rb +0 -239
- data/spec/unit/knife/bootstrap_options_spec.rb +0 -172
- data/spec/unit/knife/bootstrap_template_spec.rb +0 -139
- data/spec/unit/knife/bootstrap_windows_winrm_spec.rb +0 -410
- data/spec/unit/knife/core/windows_bootstrap_context_spec.rb +0 -292
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9df0cbd0a270e724605457a247247450e280c06fec21039fbf6f3a7603d96e88
|
4
|
+
data.tar.gz: 0010acbcbceb5b3a95366591aa79dcacc08eb47e7c3c40da236df7ca1dc61880
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed4db6cce0bb4db8ccac3c1c59bc611f2584f5db4751462c8560639889d22070f9f5bfde616cdcc8a3e985b96395c2039b1bd1890e4d2776717083ee1e439f03
|
7
|
+
data.tar.gz: da60e7d18999d01e07c6a9510abaf07a6c8b550eead498f4d760ab044bc93ab80e95696b86c38bc4348c242e4371b41d4841c4e0b3332d1b1138dd12e1a1d816
|
@@ -19,10 +19,8 @@
|
|
19
19
|
require 'chef/knife'
|
20
20
|
require 'chef/knife/bootstrap'
|
21
21
|
require 'chef/encrypted_data_bag_item'
|
22
|
-
require 'chef/knife/core/windows_bootstrap_context'
|
23
22
|
require 'chef/knife/knife_windows_base'
|
24
|
-
|
25
|
-
#require 'chef/util/path_helper'
|
23
|
+
require 'chef/util/path_helper'
|
26
24
|
|
27
25
|
class Chef
|
28
26
|
class Knife
|
@@ -70,30 +68,11 @@ class Chef
|
|
70
68
|
:description => "Custom command to install chef-client",
|
71
69
|
:proc => Proc.new { |ic| Chef::Config[:knife][:bootstrap_install_command] = ic }
|
72
70
|
|
73
|
-
# DEPR: Remove this option in Chef 13
|
74
|
-
option :distro,
|
75
|
-
:short => "-d DISTRO",
|
76
|
-
:long => "--distro DISTRO",
|
77
|
-
:description => "Bootstrap a distro using a template. [DEPRECATED] Use -t / --bootstrap-template option instead.",
|
78
|
-
:proc => Proc.new { |v|
|
79
|
-
Chef::Log.warn("[DEPRECATED] -d / --distro option is deprecated. Use --bootstrap-template option instead.")
|
80
|
-
v
|
81
|
-
}
|
82
|
-
|
83
71
|
option :bootstrap_template,
|
84
72
|
:short => "-t TEMPLATE",
|
85
73
|
:long => "--bootstrap-template TEMPLATE",
|
86
74
|
:description => "Bootstrap Chef using a built-in or custom template. Set to the full path of an erb template or use one of the built-in templates."
|
87
75
|
|
88
|
-
# DEPR: Remove this option in Chef 13
|
89
|
-
option :template_file,
|
90
|
-
:long => "--template-file TEMPLATE",
|
91
|
-
:description => "Full path to location of template to use. [DEPRECATED] Use -t / --bootstrap-template option instead.",
|
92
|
-
:proc => Proc.new { |v|
|
93
|
-
Chef::Log.warn("[DEPRECATED] --template-file option is deprecated. Use --bootstrap-template option instead.")
|
94
|
-
v
|
95
|
-
}
|
96
|
-
|
97
76
|
option :run_list,
|
98
77
|
:short => "-r RUN_LIST",
|
99
78
|
:long => "--run-list RUN_LIST",
|
@@ -203,243 +182,6 @@ class Chef
|
|
203
182
|
:default => []
|
204
183
|
end
|
205
184
|
end
|
206
|
-
|
207
|
-
def default_bootstrap_template
|
208
|
-
"windows-chef-client-msi"
|
209
|
-
end
|
210
|
-
|
211
|
-
def bootstrap_template
|
212
|
-
# The order here is important. We want to check if we have the new Chef 12 option is set first.
|
213
|
-
# Knife cloud plugins unfortunately all set a default option for the :distro so it should be at
|
214
|
-
# the end.
|
215
|
-
config[:bootstrap_template] || config[:template_file] || config[:distro] || default_bootstrap_template
|
216
|
-
end
|
217
|
-
|
218
|
-
# TODO: This should go away when CHEF-2193 is fixed
|
219
|
-
def load_template(template=nil)
|
220
|
-
# Are we bootstrapping using an already shipped template?
|
221
|
-
|
222
|
-
template = bootstrap_template
|
223
|
-
|
224
|
-
# Use the template directly if it's a path to an actual file
|
225
|
-
if File.exists?(template)
|
226
|
-
Chef::Log.debug("Using the specified bootstrap template: #{File.dirname(template)}")
|
227
|
-
return IO.read(template).chomp
|
228
|
-
end
|
229
|
-
|
230
|
-
# Otherwise search the template directories until we find the right one
|
231
|
-
bootstrap_files = []
|
232
|
-
bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap/templates', "#{template}.erb")
|
233
|
-
bootstrap_files << File.join(Knife.chef_config_dir, "bootstrap", "#{template}.erb") if Chef::Knife.chef_config_dir
|
234
|
-
::Knife::Windows::PathHelper.all_homes('.chef', 'bootstrap', "#{template}.erb") { |p| bootstrap_files << p }
|
235
|
-
bootstrap_files << Gem.find_files(File.join("chef","knife","bootstrap","#{template}.erb"))
|
236
|
-
bootstrap_files.flatten!
|
237
|
-
|
238
|
-
template = Array(bootstrap_files).find do |bootstrap_template|
|
239
|
-
Chef::Log.debug("Looking for bootstrap template in #{File.dirname(bootstrap_template)}")
|
240
|
-
::File.exists?(bootstrap_template)
|
241
|
-
end
|
242
|
-
|
243
|
-
unless template
|
244
|
-
ui.info("Can not find bootstrap definition for #{config[:distro]}")
|
245
|
-
raise Errno::ENOENT
|
246
|
-
end
|
247
|
-
|
248
|
-
Chef::Log.debug("Found bootstrap template in #{File.dirname(template)}")
|
249
|
-
|
250
|
-
IO.read(template).chomp
|
251
|
-
end
|
252
|
-
|
253
|
-
def bootstrap_context
|
254
|
-
@bootstrap_context ||= Knife::Core::WindowsBootstrapContext.new(config, config[:run_list], Chef::Config)
|
255
|
-
end
|
256
|
-
|
257
|
-
def load_correct_secret
|
258
|
-
knife_secret_file = Chef::Config[:knife][:encrypted_data_bag_secret_file]
|
259
|
-
knife_secret = Chef::Config[:knife][:encrypted_data_bag_secret]
|
260
|
-
cli_secret_file = config[:encrypted_data_bag_secret_file]
|
261
|
-
cli_secret = config[:encrypted_data_bag_secret]
|
262
|
-
|
263
|
-
cli_secret_file = nil if cli_secret_file == knife_secret_file
|
264
|
-
cli_secret = nil if cli_secret == knife_secret
|
265
|
-
|
266
|
-
cli_secret_file = Chef::EncryptedDataBagItem.load_secret(cli_secret_file) if cli_secret_file != nil
|
267
|
-
knife_secret_file = Chef::EncryptedDataBagItem.load_secret(knife_secret_file) if knife_secret_file != nil
|
268
|
-
|
269
|
-
cli_secret_file || cli_secret || knife_secret_file || knife_secret
|
270
|
-
end
|
271
|
-
|
272
|
-
def first_boot_attributes
|
273
|
-
config[:first_boot_attributes] || config[:first_boot_attributes_from_file] || {}
|
274
|
-
end
|
275
|
-
|
276
|
-
def render_template(template=nil)
|
277
|
-
config[:first_boot_attributes] = first_boot_attributes
|
278
|
-
config[:secret] = load_correct_secret
|
279
|
-
Erubis::Eruby.new(template).evaluate(bootstrap_context)
|
280
|
-
end
|
281
|
-
|
282
|
-
def bootstrap(proto=nil)
|
283
|
-
if Chef::Config[:knife][:encrypted_data_bag_secret_file] || Chef::Config[:knife][:encrypted_data_bag_secret]
|
284
|
-
warn_chef_config_secret_key
|
285
|
-
end
|
286
|
-
|
287
|
-
set_target_architecture
|
288
|
-
|
289
|
-
# adding respond_to? so this works with pre 12.4 chef clients
|
290
|
-
validate_options! if respond_to?(:validate_options!)
|
291
|
-
|
292
|
-
@node_name = Array(@name_args).first
|
293
|
-
# back compat--templates may use this setting:
|
294
|
-
config[:server_name] = @node_name
|
295
|
-
|
296
|
-
STDOUT.sync = STDERR.sync = true
|
297
|
-
|
298
|
-
if Chef::VERSION.split('.').first.to_i == 11 && Chef::Config[:validation_key] && !File.exist?(File.expand_path(Chef::Config[:validation_key]))
|
299
|
-
ui.error("Unable to find validation key. Please verify your configuration file for validation_key config value.")
|
300
|
-
exit 1
|
301
|
-
end
|
302
|
-
|
303
|
-
if (defined?(chef_vault_handler) && chef_vault_handler.doing_chef_vault?) ||
|
304
|
-
(Chef::Config[:validation_key] && !File.exist?(File.expand_path(Chef::Config[:validation_key])))
|
305
|
-
|
306
|
-
unless locate_config_value(:chef_node_name)
|
307
|
-
ui.error("You must pass a node name with -N when bootstrapping with user credentials")
|
308
|
-
exit 1
|
309
|
-
end
|
310
|
-
|
311
|
-
client_builder.run
|
312
|
-
|
313
|
-
if client_builder.respond_to?(:client)
|
314
|
-
chef_vault_handler.run(client_builder.client)
|
315
|
-
else
|
316
|
-
chef_vault_handler.run(node_name: config[:chef_node_name])
|
317
|
-
end
|
318
|
-
|
319
|
-
bootstrap_context.client_pem = client_builder.client_path
|
320
|
-
|
321
|
-
else
|
322
|
-
ui.info("Doing old-style registration with the validation key at #{Chef::Config[:validation_key]}...")
|
323
|
-
ui.info("Delete your validation key in order to use your user credentials instead")
|
324
|
-
ui.info("")
|
325
|
-
end
|
326
|
-
|
327
|
-
wait_for_remote_response( config[:auth_timeout].to_i )
|
328
|
-
|
329
|
-
ui.info("Bootstrapping Chef on #{ui.color(@node_name, :bold)}")
|
330
|
-
# create a bootstrap.bat file on the node
|
331
|
-
# we have to run the remote commands in 2047 char chunks
|
332
|
-
create_bootstrap_bat_command do |command_chunk|
|
333
|
-
render_command_result = run_command(command_chunk)
|
334
|
-
unless render_command_result == 0
|
335
|
-
ui.error("Batch render command returned #{render_command_result}")
|
336
|
-
exit render_command_result
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
# execute the bootstrap.bat file
|
341
|
-
bootstrap_command_result = run_command(bootstrap_command)
|
342
|
-
unless bootstrap_command_result == 0
|
343
|
-
ui.error("Bootstrap command returned #{bootstrap_command_result}")
|
344
|
-
exit bootstrap_command_result
|
345
|
-
end
|
346
|
-
|
347
|
-
# exit 0
|
348
|
-
0
|
349
|
-
end
|
350
|
-
|
351
|
-
protected
|
352
|
-
|
353
|
-
# Default implementation -- override only if required by the transport
|
354
|
-
def wait_for_remote_response(wait_max_minutes)
|
355
|
-
end
|
356
|
-
|
357
|
-
def bootstrap_command
|
358
|
-
@bootstrap_command ||= "cmd.exe /C #{bootstrap_bat_file}"
|
359
|
-
end
|
360
|
-
|
361
|
-
def bootstrap_render_banner_command(chunk_num)
|
362
|
-
"cmd.exe /C echo Rendering #{bootstrap_bat_file} chunk #{chunk_num}"
|
363
|
-
end
|
364
|
-
|
365
|
-
def escape_windows_batch_characters(line)
|
366
|
-
# TODO: The commands are going to get redirected - do we need to escape &?
|
367
|
-
line.gsub!(/[(<|>)^]/).each{|m| "^#{m}"}
|
368
|
-
end
|
369
|
-
|
370
|
-
def create_bootstrap_bat_command()
|
371
|
-
chunk_num = 0
|
372
|
-
bootstrap_bat = ""
|
373
|
-
banner = bootstrap_render_banner_command(chunk_num += 1)
|
374
|
-
render_template(load_template(config[:bootstrap_template])).each_line do |line|
|
375
|
-
escape_windows_batch_characters(line)
|
376
|
-
# We are guaranteed to have a prefix "banner" command that echo's chunk number. We can
|
377
|
-
# confidently prefix every actual command with &&.
|
378
|
-
# TODO: Why does ^\n&& work directly through the commandline but not through SOAP?
|
379
|
-
render_line = " && >> #{bootstrap_bat_file} (echo.#{line.chomp.strip})"
|
380
|
-
# Windows commands are limited to 8191 characters for machines running XP or higher but
|
381
|
-
# this includes the length of environment variables after they have been expanded.
|
382
|
-
# Since we don't actually know how long %TEMP% (and it's used twice - once in the banner
|
383
|
-
# and once in every command redirection), we simply guess and set the max to 5000.
|
384
|
-
# TODO: When a more accurate method is available, fix this.
|
385
|
-
if bootstrap_bat.length + render_line.length + banner.length > 5000
|
386
|
-
# Can't fit it into this chunk? - flush (if necessary) and then try.
|
387
|
-
# Do this first because banner.length might change (e.g. due to an extra digit) and
|
388
|
-
# prevent a fit.
|
389
|
-
unless bootstrap_bat.empty?
|
390
|
-
yield banner + bootstrap_bat
|
391
|
-
bootstrap_bat = ""
|
392
|
-
banner = bootstrap_render_banner_command(chunk_num += 1)
|
393
|
-
end
|
394
|
-
# Will this ever fit?
|
395
|
-
if render_line.length + banner.length > 5000
|
396
|
-
raise "Command in bootstrap template too long by #{render_line.length + banner.length - 5000} characters : #{line}"
|
397
|
-
end
|
398
|
-
end
|
399
|
-
bootstrap_bat << render_line
|
400
|
-
end
|
401
|
-
raise "Bootstrap template was empty! Check #{config[:bootstrap_template]}" if bootstrap_bat.empty?
|
402
|
-
yield banner + bootstrap_bat
|
403
|
-
end
|
404
|
-
|
405
|
-
def bootstrap_bat_file
|
406
|
-
@bootstrap_bat_file ||= "\"%TEMP%\\bootstrap-#{Process.pid}-#{Time.now.to_i}.bat\""
|
407
|
-
end
|
408
|
-
|
409
|
-
def warn_chef_config_secret_key
|
410
|
-
ui.info "* " * 40
|
411
|
-
ui.warn(<<-WARNING)
|
412
|
-
\nSpecifying the encrypted data bag secret key using an 'encrypted_data_bag_secret'
|
413
|
-
entry in 'knife.rb' is deprecated. Please use the '--secret' or '--secret-file'
|
414
|
-
options of this command instead.
|
415
|
-
|
416
|
-
#{ui.color('IMPORTANT:', :red, :bold)} In a future version of Chef, this
|
417
|
-
behavior will be removed and any 'encrypted_data_bag_secret' entries in
|
418
|
-
'knife.rb' will be ignored completely.
|
419
|
-
WARNING
|
420
|
-
ui.info "* " * 40
|
421
|
-
end
|
422
|
-
|
423
|
-
# We allow the user to specify the desired architecture of Chef to install or we default
|
424
|
-
# to whatever the target system is.
|
425
|
-
# This is because a user might want to install a 32bit chef client on a 64bit machine
|
426
|
-
def set_target_architecture
|
427
|
-
if Chef::Config[:knife][:architecture]
|
428
|
-
raise "Do not set :architecture in your knife config, use :bootstrap_architecture."
|
429
|
-
end
|
430
|
-
|
431
|
-
if Chef::Config[:knife][:bootstrap_architecture]
|
432
|
-
bootstrap_architecture = Chef::Config[:knife][:bootstrap_architecture]
|
433
|
-
|
434
|
-
if ![:x86_64, :i386].include?(bootstrap_architecture.to_sym)
|
435
|
-
raise "Valid values for the knife config :bootstrap_architecture are i386 or x86_64. Supplied value is #{bootstrap_architecture}"
|
436
|
-
end
|
437
|
-
|
438
|
-
# The windows install script wants i686, not i386
|
439
|
-
bootstrap_architecture = :i686 if bootstrap_architecture == :i386
|
440
|
-
Chef::Config[:knife][:architecture] = bootstrap_architecture
|
441
|
-
end
|
442
|
-
end
|
443
185
|
end
|
444
186
|
end
|
445
187
|
end
|
@@ -25,13 +25,13 @@ class Chef
|
|
25
25
|
include Chef::Knife::BootstrapWindowsBase
|
26
26
|
|
27
27
|
deps do
|
28
|
-
require 'chef/knife/core/windows_bootstrap_context'
|
29
28
|
require 'chef/json_compat'
|
30
29
|
require 'tempfile'
|
31
30
|
require 'highline'
|
32
31
|
require 'net/ssh'
|
33
32
|
require 'net/ssh/multi'
|
34
33
|
Chef::Knife::Ssh.load_deps
|
34
|
+
Chef::Knife::Bootstrap.load_deps
|
35
35
|
end
|
36
36
|
|
37
37
|
banner "knife bootstrap windows ssh FQDN (options)"
|
@@ -74,17 +74,6 @@ class Chef
|
|
74
74
|
:long => "--ssh-identity-file IDENTITY_FILE",
|
75
75
|
:description => "The SSH identity file used for authentication"
|
76
76
|
|
77
|
-
# DEPR: Remove this option for the next release.
|
78
|
-
option :host_key_verification,
|
79
|
-
:long => "--[no-]host-key-verify",
|
80
|
-
:description => "Verify host key, enabled by default. [DEPRECATED] Use --host-key-verify option instead.",
|
81
|
-
:boolean => true,
|
82
|
-
:default => true,
|
83
|
-
:proc => Proc.new { |key|
|
84
|
-
Chef::Log.warn("[DEPRECATED] --host-key-verification option is deprecated. Use --host-key-verify option instead.")
|
85
|
-
config[:host_key_verify] = key
|
86
|
-
}
|
87
|
-
|
88
77
|
option :host_key_verify,
|
89
78
|
:long => "--[no-]host-key-verify",
|
90
79
|
:description => "Verify host key, enabled by default.",
|
@@ -92,23 +81,15 @@ class Chef
|
|
92
81
|
:default => true
|
93
82
|
|
94
83
|
def run
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
ssh.config[:ssh_port] = locate_config_value(:ssh_port)
|
105
|
-
ssh.config[:ssh_gateway] = locate_config_value(:ssh_gateway)
|
106
|
-
ssh.config[:identity_file] = config[:identity_file]
|
107
|
-
ssh.config[:ssh_identity_file] = config[:ssh_identity_file] || config[:identity_file]
|
108
|
-
ssh.config[:forward_agent] = config[:forward_agent]
|
109
|
-
ssh.config[:manual] = true
|
110
|
-
ssh.config[:host_key_verify] = config[:host_key_verify]
|
111
|
-
ssh.run
|
84
|
+
Chef::Application.fatal!(<<~EOM
|
85
|
+
*knife windows bootstrap ssh*
|
86
|
+
Core Chef now supports bootstrapping Windows systems without a knife plugin
|
87
|
+
|
88
|
+
Use 'knife bootstrap -o ssh' instead.
|
89
|
+
|
90
|
+
For more detail https://github.com/chef/chef/blob/master/RELEASE_NOTES.md#knife-bootstrap
|
91
|
+
EOM
|
92
|
+
)
|
112
93
|
end
|
113
94
|
|
114
95
|
end
|
@@ -31,72 +31,26 @@ class Chef
|
|
31
31
|
include Chef::Knife::WinrmCommandSharedFunctions
|
32
32
|
|
33
33
|
deps do
|
34
|
-
require 'chef/knife/core/windows_bootstrap_context'
|
35
34
|
require 'chef/json_compat'
|
36
35
|
require 'tempfile'
|
37
36
|
Chef::Knife::Winrm.load_deps
|
37
|
+
Chef::Knife::Bootstrap.load_deps
|
38
38
|
end
|
39
39
|
|
40
40
|
banner 'knife bootstrap windows winrm FQDN (options)'
|
41
41
|
|
42
42
|
def run
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
unless locate_config_value(:winrm_shell) == :cmd
|
53
|
-
ui.warn("The cmd shell is the only valid winrm-shell for 'knife bootstrap windows winrm'. Switching to the cmd shell.")
|
54
|
-
config[:winrm_shell] = :cmd
|
55
|
-
end
|
56
|
-
|
57
|
-
config[:manual] = true
|
58
|
-
configure_session
|
59
|
-
|
60
|
-
bootstrap
|
43
|
+
Chef::Application.fatal!(<<~EOM
|
44
|
+
*knife windows bootstrap winrm*
|
45
|
+
Core Chef now supports bootstrapping Windows systems without a knife plugin
|
46
|
+
|
47
|
+
Use 'knife bootstrap -o winrm' instead.
|
48
|
+
|
49
|
+
For more detail https://github.com/chef/chef/blob/master/RELEASE_NOTES.md#knife-bootstrap
|
50
|
+
EOM
|
51
|
+
)
|
61
52
|
end
|
62
53
|
|
63
|
-
protected
|
64
|
-
|
65
|
-
def wait_for_remote_response(wait_max_minutes)
|
66
|
-
wait_max_seconds = wait_max_minutes * 60
|
67
|
-
retry_interval_seconds = 10
|
68
|
-
retries_left = wait_max_seconds / retry_interval_seconds
|
69
|
-
print(ui.color("\nWaiting for remote response before bootstrap", :magenta))
|
70
|
-
wait_start_time = Time.now
|
71
|
-
begin
|
72
|
-
print(".")
|
73
|
-
# Return status of the command is non-zero, typically nil,
|
74
|
-
# for our simple echo command in cases where run_command
|
75
|
-
# swallows the exception, such as 401's. Treat such cases
|
76
|
-
# the same as the case where we encounter an exception.
|
77
|
-
status = run_command("echo . & echo Response received.")
|
78
|
-
raise RuntimeError, 'Command execution failed.' if status != 0
|
79
|
-
ui.info(ui.color("Remote node responded after #{elapsed_time_in_minutes(wait_start_time)} minutes.", :magenta))
|
80
|
-
return
|
81
|
-
rescue Errno::ECONNREFUSED => e
|
82
|
-
ui.error("Connection refused connecting to #{locate_config_value(:server_name)}:#{locate_config_value(:winrm_port)}.")
|
83
|
-
raise
|
84
|
-
rescue Exception => e
|
85
|
-
retries_left -= 1
|
86
|
-
if retries_left <= 0 || (elapsed_time_in_minutes(wait_start_time) > wait_max_minutes)
|
87
|
-
ui.error("No response received from remote node after #{elapsed_time_in_minutes(wait_start_time)} minutes, giving up.")
|
88
|
-
ui.error("Exception: #{e.message}")
|
89
|
-
raise
|
90
|
-
end
|
91
|
-
print '.'
|
92
|
-
sleep retry_interval_seconds
|
93
|
-
retry
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def elapsed_time_in_minutes(start_time)
|
98
|
-
((Time.now - start_time) / 60).round(2)
|
99
|
-
end
|
100
54
|
end
|
101
55
|
end
|
102
56
|
end
|