train-core 3.6.2 → 3.7.0
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/train/options.rb +3 -0
- data/lib/train/transports/ssh.rb +11 -2
- data/lib/train/transports/ssh_connection.rb +27 -11
- data/lib/train/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e0529be878892640599f401af47c6c012a8d060fea3113895872b0af7e24127
|
4
|
+
data.tar.gz: 4b387bc5129fbf652b37713a63d74173d8d04f3ea5dbdf9993cadf0d276f3add
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fdf259b32a3dc0f033681b2f98e164f2ef76c8b4e7f51fb5bc1fe2412a1501039cdddfc06ef409f7b235dbcefef693f97c7fff21c02d7011618fdfc5ad09a9d
|
7
|
+
data.tar.gz: 2f90638d94542daf5e70488f6fd5e592986d3a76ac6b10f188414a109b53fffc8000202ce0a853f68bc1a8c1dfee9178107da5fee2b51728a01b1863b3976baf
|
data/lib/train/options.rb
CHANGED
@@ -59,6 +59,9 @@ module Train
|
|
59
59
|
default = hm[:default]
|
60
60
|
if default.is_a? Proc
|
61
61
|
res[field] = default.call(res)
|
62
|
+
elsif hm.key?(:coerce)
|
63
|
+
field_value = hm[:coerce].call(res)
|
64
|
+
res[field] = field_value.nil? ? default : field_value
|
62
65
|
else
|
63
66
|
res[field] = default
|
64
67
|
end
|
data/lib/train/transports/ssh.rb
CHANGED
@@ -43,8 +43,8 @@ module Train::Transports
|
|
43
43
|
|
44
44
|
# common target configuration
|
45
45
|
option :host, required: true
|
46
|
-
option :port, default: 22, required: true
|
47
|
-
option :user, default: "root", required: true
|
46
|
+
option :port, default: 22, coerce: proc { |u| read_options_from_ssh_config(u, :port) }, required: true
|
47
|
+
option :user, default: "root", coerce: proc { |u| read_options_from_ssh_config(u, :user) }, required: true
|
48
48
|
option :key_files, default: nil
|
49
49
|
option :password, default: nil
|
50
50
|
|
@@ -86,6 +86,14 @@ module Train::Transports
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
+
# Returns the ssh config option like user, port from config files
|
90
|
+
# Params options [Hash], option_type [String]
|
91
|
+
# Return String
|
92
|
+
def self.read_options_from_ssh_config(options, option_type)
|
93
|
+
config_options = Net::SSH.configuration_for(options[:host], true)
|
94
|
+
config_options[option_type]
|
95
|
+
end
|
96
|
+
|
89
97
|
private
|
90
98
|
|
91
99
|
def reusable_connection?(conn_opts)
|
@@ -278,5 +286,6 @@ module Train::Transports
|
|
278
286
|
yield @connection if block_given?
|
279
287
|
@connection
|
280
288
|
end
|
289
|
+
|
281
290
|
end
|
282
291
|
end
|
@@ -32,6 +32,10 @@ class Train::Transports::SSH
|
|
32
32
|
attr_reader :hostname
|
33
33
|
attr_accessor :transport_options
|
34
34
|
|
35
|
+
# If we use the GNU timeout utility to timout a command server-side, it will
|
36
|
+
# exit with this status code if the command timed out.
|
37
|
+
GNU_TIMEOUT_EXIT_STATUS = 124
|
38
|
+
|
35
39
|
def initialize(options)
|
36
40
|
# Track IOS command retries to prevent infinite loop on IOError. This must
|
37
41
|
# be done before `super()` because the parent runs detection commands.
|
@@ -321,6 +325,9 @@ class Train::Transports::SSH
|
|
321
325
|
# wrap commands if that is configured
|
322
326
|
cmd = @cmd_wrapper.run(cmd) if @cmd_wrapper
|
323
327
|
|
328
|
+
# Timeout the command if requested and able
|
329
|
+
cmd = "timeout #{timeout}s #{cmd}" if timeout && timeoutable?(cmd)
|
330
|
+
|
324
331
|
logger.debug("[SSH] #{self} cmd = #{cmd}")
|
325
332
|
|
326
333
|
if @transport_options[:pty]
|
@@ -350,21 +357,30 @@ class Train::Transports::SSH
|
|
350
357
|
end
|
351
358
|
end
|
352
359
|
end
|
360
|
+
session.loop
|
353
361
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
unless res
|
359
|
-
logger.debug("train ssh command '#{cmd}' reached requested timeout (#{timeout}s)")
|
360
|
-
session.channels.each_value { |c| c.eof!; c.close }
|
361
|
-
raise Train::CommandTimeoutReached.new "ssh command reached timeout (#{timeout}s)"
|
362
|
-
end
|
363
|
-
else
|
364
|
-
thr.join
|
362
|
+
if timeout && timeoutable?(cmd) && exit_status == GNU_TIMEOUT_EXIT_STATUS
|
363
|
+
logger.debug("train ssh command '#{cmd}' reached requested timeout (#{timeout}s)")
|
364
|
+
session.channels.each_value { |c| c.eof!; c.close }
|
365
|
+
raise Train::CommandTimeoutReached.new "ssh command reached timeout (#{timeout}s)"
|
365
366
|
end
|
366
367
|
|
367
368
|
[exit_status, stdout, stderr]
|
368
369
|
end
|
370
|
+
|
371
|
+
# Returns true if we think we can attempt to timeout the command
|
372
|
+
def timeoutable?(cmd)
|
373
|
+
have_timeout_cli? && !cmd.include?("|") # Don't try to timeout a command that has pipes
|
374
|
+
end
|
375
|
+
|
376
|
+
# Returns true if the GNU timeout command is available
|
377
|
+
def have_timeout_cli?
|
378
|
+
return @have_timeout_cli unless @have_timeout_cli.nil?
|
379
|
+
|
380
|
+
res = session.exec!("timeout --version")
|
381
|
+
@have_timeout_cli = res.exitstatus == 0
|
382
|
+
logger.debug("train ssh have_timeout_cli status is '#{@have_timeout_cli}'")
|
383
|
+
@have_timeout_cli
|
384
|
+
end
|
369
385
|
end
|
370
386
|
end
|
data/lib/train/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: train-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chef InSpec Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-04-
|
11
|
+
date: 2021-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|