train-core 3.2.5 → 3.2.14

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f698ec478a1c770c12cf3414e5aa45c8d1597c71df29f0391530fbd9473bf3ae
4
- data.tar.gz: 5ccfc4c79998c2da7e5771f949875d56198e0cecc9bc7a1e9ad2ac6fd50c85d3
3
+ metadata.gz: c4a9a2b3342fe17d7bcbfe3fcee05215b867798a4c8f01a6924e8ac57846fa9d
4
+ data.tar.gz: 0041aaaeeb3405feda9ec52c0cdc04867245e3b9b2259a122ed9db44f4506504
5
5
  SHA512:
6
- metadata.gz: e9fed72580f067cbfee15561c6f332953e25fe0a17e39ad3b9c332877f37182d75fdf92fee0be5b5f4e134388cff86f0ee6f08a17db6aa8208faf6c7c77d3c07
7
- data.tar.gz: e42ec0bc0af78769961731c539956d8f63560589459d0e895ac45e4dba0bcfca523af937a9f76956152b3a177c906e84f5d75756dc11ae8042dec237ee41270b
6
+ metadata.gz: a8d25991efa5582a917b6eb8b89cfc4bb04c54202558043c601fa29be600f384885672cb7371f76cca5709fecb06b0c3fbdd735b6898c4fea96f39f200b987ce
7
+ data.tar.gz: c9421752289a00b535b7fdff660e9e1e19ff23e37647741e8e042a5ec31e36c9b6af1eef8445217f05905b0178981000681f1c0b0b028b623b7ef2408371da6b
@@ -2,11 +2,11 @@
2
2
  #
3
3
  # Author:: Dominik Richter (<dominik.richter@gmail.com>)
4
4
 
5
- require "train/version"
6
- require "train/options"
7
- require "train/plugins"
8
- require "train/errors"
9
- require "train/platforms"
5
+ require_relative "train/version"
6
+ require_relative "train/options"
7
+ require_relative "train/plugins"
8
+ require_relative "train/errors"
9
+ require_relative "train/platforms"
10
10
  require "uri"
11
11
 
12
12
  module Train
@@ -3,8 +3,8 @@
3
3
  # Author:: Dominik Richter (<dominik.richter@gmail.com>)
4
4
 
5
5
  module Train::Extras
6
- require "train/extras/command_wrapper"
7
- require "train/extras/stat"
6
+ require_relative "extras/command_wrapper"
7
+ require_relative "extras/stat"
8
8
 
9
9
  CommandResult = Struct.new(:stdout, :stderr, :exit_status)
10
10
  LoginCommand = Struct.new(:command, :arguments)
@@ -3,7 +3,7 @@
3
3
  # author: Christoph Hartmann
4
4
 
5
5
  require "base64"
6
- require "train/errors"
6
+ require_relative "../errors"
7
7
 
8
8
  module Train::Extras
9
9
  # Define the interface of all command wrappers.
@@ -53,47 +53,46 @@ module Train::Extras
53
53
  @user = options[:user]
54
54
  end
55
55
 
56
- def with_sudo_pty
57
- old_pty = backend.transport_options[:pty]
58
- backend.transport_options[:pty] = true if @sudo
59
-
60
- yield
61
- ensure
62
- backend.transport_options[:pty] = old_pty
63
- end
64
-
65
56
  # (see CommandWrapperBase::verify)
66
57
  def verify
67
58
  cmd = if @sudo
68
59
  # Wrap it up. It needs /dev/null on the outside to disable stdin
69
- "bash -c '(#{run("-v")}) < /dev/null'"
60
+ # NOTE: can't use @sudo_command because -v conflicts with -E.
61
+ # See test-kitchen's use of this variable for conflict.
62
+ "sh -c '(sudo -v) < /dev/null'"
70
63
  else
71
64
  run("echo")
72
65
  end
73
66
 
74
67
  # rubocop:disable Style/BlockDelimiters
75
- res = with_sudo_pty {
68
+ res = @backend.with_sudo_pty {
76
69
  @backend.run_command(cmd)
77
70
  }
78
71
  return nil if res.exit_status == 0
79
72
 
80
- rawerr = res.stdout + " " + res.stderr
81
-
82
- {
83
- "Sorry, try again" => ["Wrong sudo password.", :bad_sudo_password],
84
- "sudo: no tty present and no askpass program specified" =>
85
- ["Sudo requires a password, please configure it.", :sudo_password_required],
86
- "sudo: command not found" =>
87
- ["Can't find sudo command. Please either install and "\
88
- "configure it on the target or deactivate sudo.", :sudo_command_not_found],
89
- "sudo: sorry, you must have a tty to run sudo" =>
90
- ["Sudo requires a TTY. Please see the README on how to configure "\
91
- "sudo to allow for non-interactive usage.", :sudo_no_tty],
92
- }.each do |sudo, human|
93
- rawerr = human if rawerr.include? sudo
73
+ rawerr = "#{res.stdout} #{res.stderr}".strip
74
+
75
+ case rawerr
76
+ when "Sorry, try again"
77
+ ["Wrong sudo password.", :bad_sudo_password]
78
+ when "sudo: no tty present and no askpass program specified"
79
+ ["Sudo requires a password, please configure it.", :sudo_password_required]
80
+ when "sudo: command not found"
81
+ ["Can't find sudo command. Please either install and "\
82
+ "configure it on the target or deactivate sudo.", :sudo_command_not_found]
83
+ when "sudo: sorry, you must have a tty to run sudo"
84
+ ["Sudo requires a TTY. Please see the README on how to configure "\
85
+ "sudo to allow for non-interactive usage.", :sudo_no_tty]
86
+ else
87
+ [rawerr, nil]
94
88
  end
89
+ end
95
90
 
96
- rawerr
91
+ def verify!
92
+ msg, reason = verify
93
+ return nil unless msg
94
+
95
+ raise Train::UserError.new("Sudo failed: #{msg}", reason)
97
96
  end
98
97
 
99
98
  # (see CommandWrapperBase::run)
@@ -191,15 +190,11 @@ module Train::Extras
191
190
  return nil unless LinuxCommand.active?(options)
192
191
 
193
192
  res = LinuxCommand.new(transport, options)
194
- verification_res = res.verify
195
- if verification_res
196
- msg, reason = verification_res
197
- raise Train::UserError.new("Sudo failed: #{msg}", reason)
198
- end
193
+ res.verify!
194
+
199
195
  res
200
196
  elsif transport.platform.windows?
201
- res = WindowsCommand.new(transport, options)
202
- res
197
+ WindowsCommand.new(transport, options)
203
198
  end
204
199
  end
205
200
  end
@@ -35,7 +35,7 @@ module Train::Extras
35
35
 
36
36
  def self.linux_stat(shell_escaped_path, backend, follow_symlink)
37
37
  lstat = follow_symlink ? " -L" : ""
38
- format = (backend.os.esx? || backend.os[:name] == "alpine") ? "-c" : "--printf"
38
+ format = (backend.os.esx? || backend.os[:name] == "alpine" || backend.os[:name] == "yocto") ? "-c" : "--printf"
39
39
  res = backend.run_command("stat#{lstat} #{shell_escaped_path} 2>/dev/null #{format} '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'")
40
40
  # ignore the exit_code: it is != 0 if selinux labels are not supported
41
41
  # on the system.
@@ -3,9 +3,9 @@
3
3
  # author: Christoph Hartmann
4
4
  # author: Dominik Richter
5
5
 
6
- require "train/file/local"
7
- require "train/file/remote"
8
- require "train/extras/stat"
6
+ require_relative "file/local"
7
+ require_relative "file/remote"
8
+ require_relative "extras/stat"
9
9
 
10
10
  module Train
11
11
  class File # rubocop:disable Metrics/ClassLength
@@ -78,5 +78,5 @@ end
78
78
 
79
79
  # subclass requires are loaded after Train::File::Local is defined
80
80
  # to avoid superclass mismatch errors
81
- require "train/file/local/unix"
82
- require "train/file/local/windows"
81
+ require_relative "local/unix"
82
+ require_relative "local/windows"
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require "shellwords"
4
- require "train/extras/stat"
4
+ require_relative "../../extras/stat"
5
5
 
6
6
  module Train
7
7
  class File
@@ -33,8 +33,8 @@ end
33
33
 
34
34
  # subclass requires are loaded after Train::File::Remote is defined
35
35
  # to avoid superclass mismatch errors
36
- require "train/file/remote/aix"
37
- require "train/file/remote/linux"
38
- require "train/file/remote/qnx"
39
- require "train/file/remote/unix"
40
- require "train/file/remote/windows"
36
+ require_relative "remote/aix"
37
+ require_relative "remote/linux"
38
+ require_relative "remote/qnx"
39
+ require_relative "remote/unix"
40
+ require_relative "remote/windows"
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "train/file/remote/unix"
3
+ require_relative "unix"
4
4
 
5
5
  module Train
6
6
  class File
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "train/file/remote/unix"
3
+ require_relative "unix"
4
4
 
5
5
  module Train
6
6
  class File
@@ -3,7 +3,7 @@
3
3
  # author: Christoph Hartmann
4
4
  # author: Dominik Richter
5
5
 
6
- require "train/file/remote/unix"
6
+ require_relative "unix"
7
7
 
8
8
  module Train
9
9
  class File
@@ -1,13 +1,13 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "train/platforms/common"
4
- require "train/platforms/detect"
5
- require "train/platforms/detect/scanner"
6
- require "train/platforms/detect/specifications/os"
7
- require "train/platforms/detect/specifications/api"
8
- require "train/platforms/detect/uuid"
9
- require "train/platforms/family"
10
- require "train/platforms/platform"
3
+ require_relative "platforms/common"
4
+ require_relative "platforms/detect"
5
+ require_relative "platforms/detect/scanner"
6
+ require_relative "platforms/detect/specifications/os"
7
+ require_relative "platforms/detect/specifications/api"
8
+ require_relative "platforms/detect/uuid"
9
+ require_relative "platforms/family"
10
+ require_relative "platforms/platform"
11
11
 
12
12
  module Train::Platforms
13
13
  # Retrieve the current platform list
@@ -1,5 +1,5 @@
1
- require "train/platforms/detect/helpers/os_linux"
2
- require "train/platforms/detect/helpers/os_windows"
1
+ require_relative "os_linux"
2
+ require_relative "os_windows"
3
3
  require "rbconfig"
4
4
 
5
5
  module Train::Platforms::Detect::Helpers
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "train/platforms/detect/helpers/os_common"
3
+ require_relative "helpers/os_common"
4
4
 
5
5
  module Train::Platforms::Detect
6
6
  class Scanner
@@ -17,7 +17,7 @@ module Train::Platforms::Detect::Specifications
17
17
 
18
18
  plat.family("windows").in_family("os")
19
19
  .detect do
20
- # Can't return from a `proc` thus the `is_windows` shenanigans
20
+ # Can't return from a `proc` thus the `is_windows` shenanigans
21
21
  is_windows = false
22
22
  is_windows = true if winrm?
23
23
 
@@ -25,7 +25,7 @@ module Train::Platforms::Detect::Specifications
25
25
  is_windows = true if ruby_host_os(/mswin|mingw32|windows/)
26
26
  end
27
27
 
28
- # Try to detect windows even for ssh transport
28
+ # Try to detect windows even for ssh transport
29
29
  if !is_windows && detect_windows == true
30
30
  is_windows = true
31
31
  end
@@ -41,8 +41,8 @@ module Train::Platforms::Detect::Specifications
41
41
  # unix master family
42
42
  plat.family("unix").in_family("os")
43
43
  .detect do
44
- # we want to catch a special case here where cisco commands
45
- # don't return an exit status and still print to stdout
44
+ # we want to catch a special case here where cisco commands
45
+ # don't return an exit status and still print to stdout
46
46
  if unix_uname_s =~ /./ && !unix_uname_s.start_with?("Line has invalid autocommand ") && !unix_uname_s.start_with?("The command you have entered")
47
47
  @platform[:arch] = unix_uname_m
48
48
  true
@@ -92,7 +92,7 @@ module Train::Platforms::Detect::Specifications
92
92
  true
93
93
  end
94
94
 
95
- # if we get this far we have to be some type of debian
95
+ # if we get this far we have to be some type of debian
96
96
  @platform[:release] = unix_file_contents("/etc/debian_version").chomp
97
97
  true
98
98
  end
@@ -136,9 +136,9 @@ module Train::Platforms::Detect::Specifications
136
136
  # redhat family
137
137
  plat.family("redhat").in_family("linux")
138
138
  .detect do
139
- # I am not sure this returns true for all redhats in this family
140
- # for now we are going to just try each platform
141
- # return true unless unix_file_contents('/etc/redhat-release').nil?
139
+ # I am not sure this returns true for all redhats in this family
140
+ # for now we are going to just try each platform
141
+ # return true unless unix_file_contents('/etc/redhat-release').nil?
142
142
 
143
143
  true
144
144
  end
@@ -318,6 +318,35 @@ module Train::Platforms::Detect::Specifications
318
318
  end
319
319
  end
320
320
 
321
+ # yocto family
322
+ plat.family("yocto").in_family("linux")
323
+ .detect do
324
+ # /etc/issue isn't specific to yocto, but it's the only way to detect
325
+ # the platform because there are no other identifying files
326
+ if unix_file_contents("/etc/issue") &&
327
+ (unix_file_contents("/etc/issue").match?("Poky") ||
328
+ unix_file_contents("/etc/issue").match?("balenaOS"))
329
+ true
330
+ end
331
+ end
332
+ plat.name("yocto").title("Yocto Project Linux").in_family("yocto")
333
+ .detect do
334
+ if unix_file_contents("/etc/issue").match?("Poky")
335
+ # assuming the Poky version is preferred over the /etc/version build
336
+ @platform[:release] = unix_file_contents("/etc/issue").match('\d+(\.\d+)+')[0]
337
+ true
338
+ end
339
+ end
340
+ plat.name("balenaos").title("balenaOS Linux").in_family("yocto")
341
+ .detect do
342
+ # balenaOS does have the /etc/os-release file
343
+ if unix_file_contents("/etc/issue").match?("balenaOS") &&
344
+ linux_os_release["NAME"] =~ /balenaos/i
345
+ @platform[:release] = linux_os_release["META_BALENA_VERSION"]
346
+ true
347
+ end
348
+ end
349
+
321
350
  # brocade family detected here if device responds to 'uname' command,
322
351
  # happens when logging in as root
323
352
  plat.family("brocade").title("Brocade Family").in_family("linux")
@@ -325,9 +354,9 @@ module Train::Platforms::Detect::Specifications
325
354
  !brocade_version.nil?
326
355
  end
327
356
 
328
- # genaric linux
357
+ # generic linux
329
358
  # this should always be last in the linux family list
330
- plat.name("linux").title("Genaric Linux").in_family("linux")
359
+ plat.name("linux").title("Generic Linux").in_family("linux")
331
360
  .detect do
332
361
  true
333
362
  end
@@ -426,7 +455,7 @@ module Train::Platforms::Detect::Specifications
426
455
  true
427
456
  end
428
457
 
429
- # must be some unknown solaris
458
+ # must be some unknown solaris
430
459
  true
431
460
  end
432
461
 
@@ -457,8 +486,8 @@ module Train::Platforms::Detect::Specifications
457
486
  # bsd family
458
487
  plat.family("bsd").in_family("unix")
459
488
  .detect do
460
- # we need a better way to determin this family
461
- # for now we are going to just try each platform
489
+ # we need a better way to determine this family
490
+ # for now we are going to just try each platform
462
491
  true
463
492
  end
464
493
  plat.family("darwin").in_family("bsd")
@@ -484,7 +513,7 @@ module Train::Platforms::Detect::Specifications
484
513
  end
485
514
  plat.name("darwin").title("Darwin").in_family("darwin")
486
515
  .detect do
487
- # must be some other type of darwin
516
+ # must be some other type of darwin
488
517
  @platform[:name] = unix_uname_s.lines[0].chomp
489
518
  true
490
519
  end
@@ -3,7 +3,7 @@
3
3
 
4
4
  # Load Train. We certainly need the plugin system, and also several other parts
5
5
  # that are tightly coupled. Train itself is fairly light, and non-invasive.
6
- require "train"
6
+ require_relative "../train"
7
7
 
8
8
  # You can select from a number of test harnesses. Since Train is closely related
9
9
  # to InSpec, and InSpec uses Spec-style controls in profile code, you will
@@ -3,11 +3,11 @@
3
3
  # Author:: Dominik Richter (<dominik.richter@gmail.com>)
4
4
  # Author:: Christoph Hartmann (<chris@lollyrock.com>)
5
5
 
6
- require "train/errors"
6
+ require_relative "errors"
7
7
 
8
8
  module Train
9
9
  class Plugins
10
- require "train/plugins/transport"
10
+ require_relative "plugins/transport"
11
11
 
12
12
  class << self
13
13
  # Retrieve the current plugin registry, containing all plugin names
@@ -1,8 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
- require "train/errors"
4
- require "train/extras"
5
- require "train/file"
3
+ require_relative "../errors"
4
+ require_relative "../extras"
5
+ require_relative "../file"
6
6
  require "logger"
7
7
 
8
8
  class Train::Plugins::Transport
@@ -38,6 +38,10 @@ class Train::Plugins::Transport
38
38
  end
39
39
  end
40
40
 
41
+ def with_sudo_pty
42
+ yield
43
+ end
44
+
41
45
  # Returns cached client if caching enabled. Otherwise returns whatever is
42
46
  # given in the block.
43
47
  #
@@ -88,7 +92,7 @@ class Train::Plugins::Transport
88
92
  end
89
93
 
90
94
  def load_json(j)
91
- require "train/transports/mock"
95
+ require_relative "../transports/mock"
92
96
  j["files"].each do |path, jf|
93
97
  @cache[:file][path] = Train::Transports::Mock::Connection::File.from_json(jf)
94
98
  end
@@ -4,16 +4,16 @@
4
4
  # Author:: Christoph Hartmann (<chris@lollyrock.com>)
5
5
 
6
6
  require "logger"
7
- require "train/errors"
8
- require "train/extras"
9
- require "train/options"
7
+ require_relative "../errors"
8
+ require_relative "../extras"
9
+ require_relative "../options"
10
10
 
11
11
  class Train::Plugins
12
12
  class Transport
13
13
  include Train::Extras
14
14
  Train::Options.attach(self)
15
15
 
16
- require "train/plugins/base_connection"
16
+ require_relative "base_connection"
17
17
 
18
18
  # Initialize a new Transport object
19
19
  #
@@ -3,8 +3,8 @@
3
3
  # author: Dominik Richter
4
4
  # author: Christoph Hartmann
5
5
 
6
- require "train/plugins"
7
- require "train/errors"
6
+ require_relative "../plugins"
7
+ require_relative "../errors"
8
8
  require "mixlib/shellout"
9
9
 
10
10
  module Train::Transports
@@ -1,4 +1,4 @@
1
- require "train/plugins"
1
+ require_relative "../plugins"
2
2
  require "digest"
3
3
 
4
4
  module Train::Transports
@@ -20,7 +20,7 @@
20
20
 
21
21
  require "net/ssh"
22
22
  require "net/scp"
23
- require "train/errors"
23
+ require_relative "../errors"
24
24
 
25
25
  module Train::Transports
26
26
  # Wrapped exception for any internally raised SSH-related errors.
@@ -36,8 +36,8 @@ module Train::Transports
36
36
  class SSH < Train.plugin(1) # rubocop:disable Metrics/ClassLength
37
37
  name "ssh"
38
38
 
39
- require "train/transports/ssh_connection"
40
- require "train/transports/cisco_ios_connection"
39
+ require_relative "ssh_connection"
40
+ require_relative "cisco_ios_connection"
41
41
 
42
42
  # add options for submodules
43
43
  include_options Train::Extras::CommandWrapper
@@ -164,6 +164,15 @@ class Train::Transports::SSH
164
164
  options_to_print
165
165
  end
166
166
 
167
+ def with_sudo_pty
168
+ old_pty = transport_options[:pty]
169
+ transport_options[:pty] = true if @sudo
170
+
171
+ yield
172
+ ensure
173
+ transport_options[:pty] = old_pty
174
+ end
175
+
167
176
  private
168
177
 
169
178
  PING_COMMAND = "echo '[SSH] Established'".freeze
@@ -213,17 +222,17 @@ class Train::Transports::SSH
213
222
  retry
214
223
  end
215
224
 
216
- def file_via_connection(path)
225
+ def file_via_connection(path, *args)
217
226
  if os.aix?
218
- Train::File::Remote::Aix.new(self, path)
227
+ Train::File::Remote::Aix.new(self, path, *args)
219
228
  elsif os.solaris?
220
- Train::File::Remote::Unix.new(self, path)
229
+ Train::File::Remote::Unix.new(self, path, *args)
221
230
  elsif os[:name] == "qnx"
222
- Train::File::Remote::Qnx.new(self, path)
231
+ Train::File::Remote::Qnx.new(self, path, *args)
223
232
  elsif os.windows?
224
- Train::File::Remote::Windows.new(self, path)
233
+ Train::File::Remote::Windows.new(self, path, *args)
225
234
  else
226
- Train::File::Remote::Linux.new(self, path)
235
+ Train::File::Remote::Linux.new(self, path, *args)
227
236
  end
228
237
  end
229
238
 
@@ -3,5 +3,5 @@
3
3
  # Author:: Dominik Richter (<dominik.richter@gmail.com>)
4
4
 
5
5
  module Train
6
- VERSION = "3.2.5".freeze
6
+ VERSION = "3.2.14".freeze
7
7
  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.2.5
4
+ version: 3.2.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dominik Richter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-12-12 00:00:00.000000000 Z
11
+ date: 2020-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json