train-core 3.3.21 → 3.3.24

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4bfda9949a3f24a3c7d48f8bb23384c73f064eccfa0f44029872e13913880c9
4
- data.tar.gz: 6598c63e265c79e1344010ace35b40d1f5bd1919bb8039d4ae868c54f9f85dc5
3
+ metadata.gz: 2b4cd9dbab0f4f3706d077a9c26185998bbdc4925ef03783b90c9244e268990d
4
+ data.tar.gz: a13777cd6b9e682fae479da36147ef17cbf01cf09c2d70f3377bf916e021be0f
5
5
  SHA512:
6
- metadata.gz: aeb75022b5ff8c0f93ce22b35a6d8af8b31c8f3906fe357e502cd6f7ab8e7cb0bf55df61c8e891579b5338f875413b6c1372535e5af30d3011d54fd8b7822968
7
- data.tar.gz: 3c23b61031fe8c0e8d691929ccb9007a8272d1de9736b8c5bef1ffcfd8a3078b31f556454f6676cc9d9a2515333015852f64f8e5ce47d2313e393eb4b230f9f7
6
+ metadata.gz: 36d220f296af3ac7d239a38726c0ccf6764ff171ea73004ea700c637b05233132e79619ea05de4fedbc098493baef6ea1095126325fd988475cf4a0a05ccce66
7
+ data.tar.gz: 6f8b09680a850f138c217bbfc03ae18e44a117d08842d8ca00a7055931a39e95e3be3652a851a4904171f7a80e58776cf1ff2220affaa19833c495d28e10cbe7
@@ -40,4 +40,7 @@ module Train
40
40
 
41
41
  # Exception for when a invalid cache type is passed.
42
42
  class UnknownCacheType < Error; end
43
+
44
+ # Exception for when a command reaches configured timeout
45
+ class CommandTimeoutReached < Error; end
43
46
  end
@@ -1,7 +1,7 @@
1
1
  # author: Dominik Richter
2
2
  # author: Christoph Hartmann
3
3
 
4
- require "base64"
4
+ require "base64" unless defined?(Base64)
5
5
  require_relative "../errors"
6
6
 
7
7
  module Train::Extras
@@ -1,4 +1,4 @@
1
- require "digest/sha1"
1
+ require "digest/sha1" unless defined?(Digest::SHA1)
2
2
  require "securerandom" unless defined?(SecureRandom)
3
3
  require "json" unless defined?(JSON)
4
4
 
@@ -130,10 +130,27 @@ class Train::Plugins::Transport
130
130
  # This command accepts an optional data handler block. When provided,
131
131
  # inbound data will be published vi `data_handler.call(data)`. This can allow
132
132
  # callers to receive and render updates from remote command execution.
133
- def run_command(cmd, &data_handler)
134
- return run_command_via_connection(cmd, &data_handler) unless cache_enabled?(:command)
135
-
136
- @cache[:command][cmd] ||= run_command_via_connection(cmd, &data_handler)
133
+ #
134
+ # @param [String] the command to run
135
+ # @param [Hash] optional hash of options for this command. The derived connection
136
+ # class's implementation of run_command_via_connection should receive
137
+ # and apply these options.
138
+ def run_command(cmd, opts = {}, &data_handler)
139
+ # Some implementations do not accept an opts argument.
140
+ # We cannot update all implementations to accept opts due to them being separate plugins.
141
+ # Therefore here we check the implementation's arity to maintain compatibility.
142
+ case method(:run_command_via_connection).arity.abs
143
+ when 1
144
+ return run_command_via_connection(cmd, &data_handler) unless cache_enabled?(:command)
145
+
146
+ @cache[:command][cmd] ||= run_command_via_connection(cmd, &data_handler)
147
+ when 2
148
+ return run_command_via_connection(cmd, opts, &data_handler) unless cache_enabled?(:command)
149
+
150
+ @cache[:command][cmd] ||= run_command_via_connection(cmd, opts, &data_handler)
151
+ else
152
+ raise NotImplementedError, "#{self.class} does not implement run_command_via_connection with arity #{method(:run_command_via_connection).arity}"
153
+ end
137
154
  end
138
155
 
139
156
  # This is the main file call for all connections. This will call the private
@@ -112,7 +112,7 @@ module Train::Transports
112
112
 
113
113
  class WindowsShellRunner
114
114
  require "json" unless defined?(JSON)
115
- require "base64"
115
+ require "base64" unless defined?(Base64)
116
116
 
117
117
  def initialize(powershell_cmd = "powershell")
118
118
  @powershell_cmd = powershell_cmd
@@ -136,7 +136,7 @@ module Train::Transports
136
136
 
137
137
  class WindowsPipeRunner
138
138
  require "json" unless defined?(JSON)
139
- require "base64"
139
+ require "base64" unless defined?(Base64)
140
140
  require "securerandom" unless defined?(SecureRandom)
141
141
 
142
142
  def initialize(powershell_cmd = "powershell")
@@ -1,5 +1,5 @@
1
1
  require_relative "../plugins"
2
- require "digest"
2
+ require "digest" unless defined?(Digest)
3
3
 
4
4
  module Train::Transports
5
5
  class Mock < Train.plugin(1)
@@ -235,12 +235,12 @@ class Train::Transports::SSH
235
235
  end
236
236
  end
237
237
 
238
- def run_command_via_connection(cmd, &data_handler)
238
+ def run_command_via_connection(cmd, opts = {}, &data_handler)
239
239
  cmd.dup.force_encoding("binary") if cmd.respond_to?(:force_encoding)
240
240
 
241
241
  reset_session if session.closed?
242
242
 
243
- exit_status, stdout, stderr = execute_on_channel(cmd, &data_handler)
243
+ exit_status, stdout, stderr = execute_on_channel(cmd, opts, &data_handler)
244
244
 
245
245
  # Since `@session.loop` succeeded, reset the IOS command retry counter
246
246
  @ios_cmd_retries = 0
@@ -297,7 +297,8 @@ class Train::Transports::SSH
297
297
  # not received.
298
298
  #
299
299
  # @api private
300
- def execute_on_channel(cmd)
300
+ def execute_on_channel(cmd, opts)
301
+ timeout = opts[:timeout]&.to_i
301
302
  stdout = ""
302
303
  stderr = ""
303
304
  exit_status = nil
@@ -307,7 +308,7 @@ class Train::Transports::SSH
307
308
 
308
309
  logger.debug("[SSH] #{self} cmd = #{cmd}")
309
310
 
310
- if @transport_options[:pty]
311
+ if @transport_options[:pty] || timeout
311
312
  channel.request_pty do |_ch, success|
312
313
  raise Train::Transports::SSHPTYFailed, "Requesting PTY failed" unless success
313
314
  end
@@ -334,7 +335,20 @@ class Train::Transports::SSH
334
335
  end
335
336
  end
336
337
  end
337
- session.loop
338
+
339
+ thr = Thread.new { session.loop }
340
+
341
+ if timeout
342
+ res = thr.join(timeout)
343
+ unless res
344
+ logger.info("ssh command reached requested timeout (#{timeout}s)")
345
+ session.channels.each_value { |c| c.eof!; c.close }
346
+ raise Train::CommandTimeoutReached.new "ssh command reached timeout (#{timeout}s)"
347
+ end
348
+ else
349
+ thr.join
350
+ end
351
+
338
352
  [exit_status, stdout, stderr]
339
353
  end
340
354
  end
@@ -2,5 +2,5 @@
2
2
  # Author:: Dominik Richter (<dominik.richter@gmail.com>)
3
3
 
4
4
  module Train
5
- VERSION = "3.3.21".freeze
5
+ VERSION = "3.3.24".freeze
6
6
  end
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.3.21
4
+ version: 3.3.24
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: 2020-09-14 00:00:00.000000000 Z
11
+ date: 2020-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable