train-core 3.2.5 → 3.2.14

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: 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