train-core 3.3.4 → 3.3.24
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.rb +1 -2
- data/lib/train/errors.rb +3 -1
- data/lib/train/extras.rb +0 -1
- data/lib/train/extras/command_wrapper.rb +1 -2
- data/lib/train/extras/stat.rb +0 -1
- data/lib/train/file.rb +0 -1
- data/lib/train/file/local.rb +0 -2
- data/lib/train/file/local/unix.rb +1 -3
- data/lib/train/file/local/windows.rb +0 -2
- data/lib/train/file/remote.rb +0 -2
- data/lib/train/file/remote/aix.rb +0 -2
- data/lib/train/file/remote/linux.rb +0 -2
- data/lib/train/file/remote/qnx.rb +0 -1
- data/lib/train/file/remote/unix.rb +1 -1
- data/lib/train/file/remote/windows.rb +0 -2
- data/lib/train/options.rb +0 -1
- data/lib/train/platforms.rb +0 -2
- data/lib/train/platforms/common.rb +0 -2
- data/lib/train/platforms/detect.rb +0 -2
- data/lib/train/platforms/detect/helpers/os_common.rb +17 -9
- data/lib/train/platforms/detect/helpers/os_linux.rb +0 -2
- data/lib/train/platforms/detect/scanner.rb +0 -2
- data/lib/train/platforms/detect/specifications/api.rb +0 -2
- data/lib/train/platforms/detect/specifications/os.rb +2 -2
- data/lib/train/platforms/detect/uuid.rb +3 -3
- data/lib/train/platforms/family.rb +0 -2
- data/lib/train/platforms/platform.rb +1 -3
- data/lib/train/plugin_test_helper.rb +5 -5
- data/lib/train/plugins.rb +1 -2
- data/lib/train/plugins/base_connection.rb +22 -7
- data/lib/train/plugins/transport.rb +0 -1
- data/lib/train/transports/cisco_ios_connection.rb +0 -2
- data/lib/train/transports/local.rb +7 -8
- data/lib/train/transports/mock.rb +1 -1
- data/lib/train/transports/ssh.rb +2 -3
- data/lib/train/transports/ssh_connection.rb +21 -8
- data/lib/train/version.rb +1 -2
- 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: 2b4cd9dbab0f4f3706d077a9c26185998bbdc4925ef03783b90c9244e268990d
|
4
|
+
data.tar.gz: a13777cd6b9e682fae479da36147ef17cbf01cf09c2d70f3377bf916e021be0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36d220f296af3ac7d239a38726c0ccf6764ff171ea73004ea700c637b05233132e79619ea05de4fedbc098493baef6ea1095126325fd988475cf4a0a05ccce66
|
7
|
+
data.tar.gz: 6f8b09680a850f138c217bbfc03ae18e44a117d08842d8ca00a7055931a39e95e3be3652a851a4904171f7a80e58776cf1ff2220affaa19833c495d28e10cbe7
|
data/lib/train.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
#
|
3
2
|
# Author:: Dominik Richter (<dominik.richter@gmail.com>)
|
4
3
|
|
@@ -7,7 +6,7 @@ require_relative "train/options"
|
|
7
6
|
require_relative "train/plugins"
|
8
7
|
require_relative "train/errors"
|
9
8
|
require_relative "train/platforms"
|
10
|
-
require "addressable/uri"
|
9
|
+
require "addressable/uri" unless defined?(Addressable::URI)
|
11
10
|
|
12
11
|
module Train
|
13
12
|
# Create a new transport instance, with the plugin indicated by the
|
data/lib/train/errors.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
#
|
3
2
|
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
3
|
# Author:: Dominik Richter (<dominik.richter@gmail.com>)
|
@@ -41,4 +40,7 @@ module Train
|
|
41
40
|
|
42
41
|
# Exception for when a invalid cache type is passed.
|
43
42
|
class UnknownCacheType < Error; end
|
43
|
+
|
44
|
+
# Exception for when a command reaches configured timeout
|
45
|
+
class CommandTimeoutReached < Error; end
|
44
46
|
end
|
data/lib/train/extras.rb
CHANGED
data/lib/train/extras/stat.rb
CHANGED
data/lib/train/file.rb
CHANGED
data/lib/train/file/local.rb
CHANGED
data/lib/train/file/remote.rb
CHANGED
data/lib/train/options.rb
CHANGED
data/lib/train/platforms.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative "os_linux"
|
2
2
|
require_relative "os_windows"
|
3
|
-
require "rbconfig"
|
3
|
+
require "rbconfig" unless defined?(RbConfig)
|
4
4
|
|
5
5
|
module Train::Platforms::Detect::Helpers
|
6
6
|
module OSCommon
|
@@ -34,16 +34,24 @@ module Train::Platforms::Detect::Helpers
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def command_output(cmd)
|
37
|
-
res = @backend.run_command(cmd)
|
38
|
-
|
39
|
-
|
37
|
+
res = @backend.run_command(cmd)
|
38
|
+
stdout = res.stdout
|
39
|
+
stderr = res.stderr
|
40
|
+
# When you try to execute command using ssh connection as root user and you have provided ssh user identity file
|
41
|
+
# it gives standard output to login as authorized user other than root. To show this standard output as an error
|
40
42
|
# to user we are matching the string of stdout and raising the error here so that user gets exact information.
|
41
|
-
if @backend.class.to_s == "Train::Transports::SSH::Connection"
|
42
|
-
|
43
|
+
if @backend.class.to_s == "Train::Transports::SSH::Connection"
|
44
|
+
if stdout =~ /Please login as the user/
|
45
|
+
raise Train::UserError, "SSH failed: #{stdout}"
|
46
|
+
end
|
47
|
+
|
48
|
+
if stderr =~ /WARNING: Your password has expired/
|
49
|
+
raise Train::UserError, "SSH failed: #{stderr}"
|
50
|
+
end
|
43
51
|
end
|
44
52
|
|
45
|
-
|
46
|
-
|
53
|
+
stdout.strip! unless stdout.nil?
|
54
|
+
stdout
|
47
55
|
end
|
48
56
|
|
49
57
|
def unix_uname_s
|
@@ -157,7 +165,7 @@ module Train::Platforms::Detect::Helpers
|
|
157
165
|
def json_cmd(cmd)
|
158
166
|
cmd = @backend.run_command(cmd)
|
159
167
|
if cmd.exit_status == 0 && !cmd.stdout.empty?
|
160
|
-
require "json"
|
168
|
+
require "json" unless defined?(JSON)
|
161
169
|
eos_ver = JSON.parse(cmd.stdout)
|
162
170
|
@platform[:release] = eos_ver["version"]
|
163
171
|
@platform[:arch] = eos_ver["architecture"]
|
@@ -128,7 +128,7 @@ module Train::Platforms::Detect::Specifications
|
|
128
128
|
|
129
129
|
declare_lsb("scientific", "Scientific Linux", "redhat", /scientific/i)
|
130
130
|
|
131
|
-
declare_lsb("xenserver", "
|
131
|
+
declare_lsb("xenserver", "Xenserver Linux", "redhat", /xenserver/i)
|
132
132
|
|
133
133
|
declare_instance("parallels-release", "Parallels Linux", "redhat") do
|
134
134
|
if (raw = unix_file_contents("/etc/parallels-release"))
|
@@ -357,7 +357,7 @@ module Train::Platforms::Detect::Specifications
|
|
357
357
|
declare_instance("mac_os_x", "macOS X", "darwin") do
|
358
358
|
cmd = unix_file_contents("/System/Library/CoreServices/SystemVersion.plist")
|
359
359
|
@platform[:uuid_command] = "system_profiler SPHardwareDataType | awk '/UUID/ { print $3; }'"
|
360
|
-
cmd =~ /Mac OS X/i
|
360
|
+
cmd =~ /Mac OS X|macOS/i
|
361
361
|
end
|
362
362
|
|
363
363
|
declare_instance("darwin", "Darwin", "darwin") do
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Train::Platforms
|
4
2
|
class Platform
|
5
3
|
include Train::Platforms::Common
|
@@ -47,7 +45,7 @@ module Train::Platforms
|
|
47
45
|
@uuid ||= Train::Platforms::Detect::UUID.new(self).find_or_create_uuid.downcase
|
48
46
|
end
|
49
47
|
|
50
|
-
# This is for
|
48
|
+
# This is for backwards compatibility with
|
51
49
|
# the current inspec os resource.
|
52
50
|
def[](name)
|
53
51
|
if respond_to?(name)
|
@@ -13,13 +13,13 @@ require "minitest/spec"
|
|
13
13
|
require "minitest/autorun"
|
14
14
|
|
15
15
|
# Data formats commonly used in testing
|
16
|
-
require "json"
|
17
|
-
require "ostruct"
|
16
|
+
require "json" unless defined?(JSON)
|
17
|
+
require "ostruct" unless defined?(OpenStruct)
|
18
18
|
|
19
19
|
# Utilities often needed
|
20
|
-
require "fileutils"
|
21
|
-
require "tmpdir"
|
22
|
-
require "pathname"
|
20
|
+
require "fileutils" unless defined?(FileUtils)
|
21
|
+
require "tmpdir" unless defined?(Dir.mktmpdir)
|
22
|
+
require "pathname" unless defined?(Pathname)
|
23
23
|
|
24
24
|
# You might want to put some debugging tools here. We run tests to find bugs,
|
25
25
|
# after all.
|
data/lib/train/plugins.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
#
|
3
2
|
# Author:: Dominik Richter (<dominik.richter@gmail.com>)
|
4
3
|
# Author:: Christoph Hartmann (<chris@lollyrock.com>)
|
@@ -24,7 +23,7 @@ module Train
|
|
24
23
|
# Create a versioned plugin by providing the transport layer plugin version
|
25
24
|
# to this method. It will then select the correct class to inherit from.
|
26
25
|
#
|
27
|
-
# The plugin version
|
26
|
+
# The plugin version determines what methods will be available to your plugin.
|
28
27
|
#
|
29
28
|
# @param [Int] version = 1 the plugin version to use
|
30
29
|
# @return [Transport] the versioned transport base class
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require_relative "../errors"
|
4
2
|
require_relative "../extras"
|
5
3
|
require_relative "../file"
|
@@ -132,10 +130,27 @@ class Train::Plugins::Transport
|
|
132
130
|
# This command accepts an optional data handler block. When provided,
|
133
131
|
# inbound data will be published vi `data_handler.call(data)`. This can allow
|
134
132
|
# callers to receive and render updates from remote command execution.
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
139
154
|
end
|
140
155
|
|
141
156
|
# This is the main file call for all connections. This will call the private
|
@@ -160,7 +175,7 @@ class Train::Plugins::Transport
|
|
160
175
|
# service is preferred to simply waiting on a socket to become
|
161
176
|
# available.
|
162
177
|
def wait_until_ready
|
163
|
-
# this method may be left unimplemented if that is
|
178
|
+
# this method may be left unimplemented if that is applicable log
|
164
179
|
end
|
165
180
|
|
166
181
|
private
|
@@ -1,11 +1,10 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
#
|
3
2
|
# author: Dominik Richter
|
4
3
|
# author: Christoph Hartmann
|
5
4
|
|
6
5
|
require_relative "../plugins"
|
7
6
|
require_relative "../errors"
|
8
|
-
require "mixlib/shellout"
|
7
|
+
require "mixlib/shellout" unless defined?(Mixlib::ShellOut)
|
9
8
|
|
10
9
|
module Train::Transports
|
11
10
|
class Local < Train.plugin(1)
|
@@ -112,8 +111,8 @@ module Train::Transports
|
|
112
111
|
end
|
113
112
|
|
114
113
|
class WindowsShellRunner
|
115
|
-
require "json"
|
116
|
-
require "base64"
|
114
|
+
require "json" unless defined?(JSON)
|
115
|
+
require "base64" unless defined?(Base64)
|
117
116
|
|
118
117
|
def initialize(powershell_cmd = "powershell")
|
119
118
|
@powershell_cmd = powershell_cmd
|
@@ -136,9 +135,9 @@ module Train::Transports
|
|
136
135
|
end
|
137
136
|
|
138
137
|
class WindowsPipeRunner
|
139
|
-
require "json"
|
140
|
-
require "base64"
|
141
|
-
require "securerandom"
|
138
|
+
require "json" unless defined?(JSON)
|
139
|
+
require "base64" unless defined?(Base64)
|
140
|
+
require "securerandom" unless defined?(SecureRandom)
|
142
141
|
|
143
142
|
def initialize(powershell_cmd = "powershell")
|
144
143
|
@powershell_cmd = powershell_cmd
|
@@ -147,7 +146,7 @@ module Train::Transports
|
|
147
146
|
end
|
148
147
|
|
149
148
|
# @param cmd The command to execute
|
150
|
-
# @return Local::
|
149
|
+
# @return Local::CommandResult with stdout, stderr and exitstatus
|
151
150
|
# Note that exitstatus ($?) in PowerShell is boolean, but we use a numeric exit code.
|
152
151
|
# A command that succeeds without setting an exit code will have exitstatus 0
|
153
152
|
# A command that exits with an exit code will have that value as exitstatus
|
data/lib/train/transports/ssh.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
#
|
3
2
|
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
3
|
# Author:: Dominik Richter (<dominik.richter@gmail.com>)
|
@@ -18,7 +17,7 @@
|
|
18
17
|
# See the License for the specific language governing permissions and
|
19
18
|
# limitations under the License.
|
20
19
|
|
21
|
-
require "net/ssh"
|
20
|
+
require "net/ssh" unless defined?(Net::SSH)
|
22
21
|
require "net/scp"
|
23
22
|
require_relative "../errors"
|
24
23
|
|
@@ -238,7 +237,7 @@ module Train::Transports
|
|
238
237
|
# Creates a new SSH Connection instance and save it for potential future
|
239
238
|
# reuse.
|
240
239
|
#
|
241
|
-
# @param options [Hash]
|
240
|
+
# @param options [Hash] connection options
|
242
241
|
# @return [Ssh::Connection] an SSH Connection instance
|
243
242
|
# @api private
|
244
243
|
def create_new_connection(options, &block)
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
#
|
3
2
|
# Author:: Fletcher Nichol (<fnichol@nichol.ca>)
|
4
3
|
# Author:: Dominik Richter (<dominik.richter@gmail.com>)
|
@@ -18,9 +17,9 @@
|
|
18
17
|
# See the License for the specific language governing permissions and
|
19
18
|
# limitations under the License.
|
20
19
|
|
21
|
-
require "net/ssh"
|
20
|
+
require "net/ssh" unless defined?(Net::SSH)
|
22
21
|
require "net/scp"
|
23
|
-
require "timeout"
|
22
|
+
require "timeout" unless defined?(Timeout)
|
24
23
|
|
25
24
|
class Train::Transports::SSH
|
26
25
|
# A Connection instance can be generated and re-generated, given new
|
@@ -236,12 +235,12 @@ class Train::Transports::SSH
|
|
236
235
|
end
|
237
236
|
end
|
238
237
|
|
239
|
-
def run_command_via_connection(cmd, &data_handler)
|
238
|
+
def run_command_via_connection(cmd, opts = {}, &data_handler)
|
240
239
|
cmd.dup.force_encoding("binary") if cmd.respond_to?(:force_encoding)
|
241
240
|
|
242
241
|
reset_session if session.closed?
|
243
242
|
|
244
|
-
exit_status, stdout, stderr = execute_on_channel(cmd, &data_handler)
|
243
|
+
exit_status, stdout, stderr = execute_on_channel(cmd, opts, &data_handler)
|
245
244
|
|
246
245
|
# Since `@session.loop` succeeded, reset the IOS command retry counter
|
247
246
|
@ios_cmd_retries = 0
|
@@ -298,7 +297,8 @@ class Train::Transports::SSH
|
|
298
297
|
# not received.
|
299
298
|
#
|
300
299
|
# @api private
|
301
|
-
def execute_on_channel(cmd)
|
300
|
+
def execute_on_channel(cmd, opts)
|
301
|
+
timeout = opts[:timeout]&.to_i
|
302
302
|
stdout = ""
|
303
303
|
stderr = ""
|
304
304
|
exit_status = nil
|
@@ -308,7 +308,7 @@ class Train::Transports::SSH
|
|
308
308
|
|
309
309
|
logger.debug("[SSH] #{self} cmd = #{cmd}")
|
310
310
|
|
311
|
-
if @transport_options[:pty]
|
311
|
+
if @transport_options[:pty] || timeout
|
312
312
|
channel.request_pty do |_ch, success|
|
313
313
|
raise Train::Transports::SSHPTYFailed, "Requesting PTY failed" unless success
|
314
314
|
end
|
@@ -335,7 +335,20 @@ class Train::Transports::SSH
|
|
335
335
|
end
|
336
336
|
end
|
337
337
|
end
|
338
|
-
|
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
|
+
|
339
352
|
[exit_status, stdout, stderr]
|
340
353
|
end
|
341
354
|
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.3.
|
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-
|
11
|
+
date: 2020-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|