train-core 2.1.7 → 2.1.13

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/train.rb +20 -20
  3. data/lib/train/errors.rb +1 -1
  4. data/lib/train/extras.rb +2 -2
  5. data/lib/train/extras/command_wrapper.rb +24 -24
  6. data/lib/train/extras/stat.rb +27 -27
  7. data/lib/train/file.rb +30 -30
  8. data/lib/train/file/local.rb +8 -8
  9. data/lib/train/file/local/unix.rb +5 -5
  10. data/lib/train/file/local/windows.rb +1 -1
  11. data/lib/train/file/remote.rb +8 -8
  12. data/lib/train/file/remote/aix.rb +1 -1
  13. data/lib/train/file/remote/linux.rb +2 -2
  14. data/lib/train/file/remote/qnx.rb +8 -8
  15. data/lib/train/file/remote/unix.rb +10 -14
  16. data/lib/train/file/remote/windows.rb +5 -5
  17. data/lib/train/globals.rb +1 -1
  18. data/lib/train/options.rb +8 -8
  19. data/lib/train/platforms.rb +8 -8
  20. data/lib/train/platforms/common.rb +1 -1
  21. data/lib/train/platforms/detect/helpers/os_common.rb +36 -32
  22. data/lib/train/platforms/detect/helpers/os_linux.rb +12 -12
  23. data/lib/train/platforms/detect/helpers/os_windows.rb +27 -29
  24. data/lib/train/platforms/detect/scanner.rb +4 -4
  25. data/lib/train/platforms/detect/specifications/api.rb +8 -8
  26. data/lib/train/platforms/detect/specifications/os.rb +252 -252
  27. data/lib/train/platforms/detect/uuid.rb +5 -7
  28. data/lib/train/platforms/platform.rb +9 -5
  29. data/lib/train/plugin_test_helper.rb +12 -12
  30. data/lib/train/plugins.rb +5 -5
  31. data/lib/train/plugins/base_connection.rb +13 -13
  32. data/lib/train/plugins/transport.rb +7 -7
  33. data/lib/train/transports/cisco_ios_connection.rb +20 -20
  34. data/lib/train/transports/local.rb +22 -22
  35. data/lib/train/transports/mock.rb +33 -35
  36. data/lib/train/transports/ssh.rb +47 -47
  37. data/lib/train/transports/ssh_connection.rb +28 -28
  38. data/lib/train/transports/winrm.rb +37 -37
  39. data/lib/train/transports/winrm_connection.rb +12 -12
  40. data/lib/train/version.rb +1 -1
  41. metadata +2 -2
@@ -12,7 +12,7 @@ module Train
12
12
  end
13
13
 
14
14
  def content
15
- @content ||= ::File.read(@path, encoding: 'UTF-8')
15
+ @content ||= ::File.read(@path, encoding: "UTF-8")
16
16
  rescue StandardError => _
17
17
  nil
18
18
  end
@@ -23,7 +23,7 @@ module Train
23
23
  @link_path ||= ::File.realpath(@path)
24
24
  rescue Errno::ELOOP => _
25
25
  # Leave it blank on symbolic loop, same as readlink
26
- @link_path = ''
26
+ @link_path = ""
27
27
  end
28
28
  end
29
29
 
@@ -42,13 +42,13 @@ module Train
42
42
 
43
43
  def type
44
44
  case ::File.ftype(@path)
45
- when 'blockSpecial'
45
+ when "blockSpecial"
46
46
  :block_device
47
- when 'characterSpecial'
47
+ when "characterSpecial"
48
48
  :character_device
49
- when 'link'
49
+ when "link"
50
50
  :symlink
51
- when 'fifo'
51
+ when "fifo"
52
52
  :pipe
53
53
  else
54
54
  ::File.ftype(@path).to_sym
@@ -76,5 +76,5 @@ end
76
76
 
77
77
  # subclass requires are loaded after Train::File::Local is defined
78
78
  # to avoid superclass mismatch errors
79
- require 'train/file/local/unix'
80
- require 'train/file/local/windows'
79
+ require "train/file/local/unix"
80
+ require "train/file/local/windows"
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'shellwords'
4
- require 'train/extras/stat'
3
+ require "shellwords"
4
+ require "train/extras/stat"
5
5
 
6
6
  module Train
7
7
  class File
@@ -36,9 +36,9 @@ module Train
36
36
  gid: file_stat.gid,
37
37
  }
38
38
 
39
- lstat = @follow_symlink ? ' -L' : ''
39
+ lstat = @follow_symlink ? " -L" : ""
40
40
  res = @backend.run_command("stat#{lstat} #{@spath} 2>/dev/null --printf '%C'")
41
- if res.exit_status == 0 && !res.stdout.empty? && res.stdout != '?'
41
+ if res.exit_status == 0 && !res.stdout.empty? && res.stdout != "?"
42
42
  @stat[:selinux_label] = res.stdout.strip
43
43
  end
44
44
 
@@ -79,7 +79,7 @@ module Train
79
79
  end
80
80
 
81
81
  UNIX_MODE_OWNERS = {
82
- all: 00777,
82
+ all: 00777,
83
83
  owner: 00700,
84
84
  group: 00070,
85
85
  other: 00007,
@@ -9,7 +9,7 @@ module Train
9
9
  def sanitize_filename(path)
10
10
  return if path.nil?
11
11
  # we do not filter :, backslash and forward slash, since they are part of the path
12
- @spath = path.gsub(/[<>"|?*]/, '')
12
+ @spath = path.gsub(/[<>"|?*]/, "")
13
13
  end
14
14
 
15
15
  def product_version
@@ -3,9 +3,9 @@
3
3
  module Train
4
4
  class File
5
5
  class Remote < Train::File
6
- def basename(suffix = nil, sep = '/')
7
- fail 'Not yet supported: Suffix in file.basename' unless suffix.nil?
8
- @basename ||= detect_filename(path, sep || '/')
6
+ def basename(suffix = nil, sep = "/")
7
+ raise "Not yet supported: Suffix in file.basename" unless suffix.nil?
8
+ @basename ||= detect_filename(path, sep || "/")
9
9
  end
10
10
 
11
11
  def stat
@@ -29,8 +29,8 @@ end
29
29
 
30
30
  # subclass requires are loaded after Train::File::Remote is defined
31
31
  # to avoid superclass mismatch errors
32
- require 'train/file/remote/aix'
33
- require 'train/file/remote/linux'
34
- require 'train/file/remote/qnx'
35
- require 'train/file/remote/unix'
36
- require 'train/file/remote/windows'
32
+ require "train/file/remote/aix"
33
+ require "train/file/remote/linux"
34
+ require "train/file/remote/qnx"
35
+ require "train/file/remote/unix"
36
+ require "train/file/remote/windows"
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'train/file/remote/unix'
3
+ require "train/file/remote/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 "train/file/remote/unix"
4
4
 
5
5
  module Train
6
6
  class File
@@ -10,7 +10,7 @@ module Train
10
10
  return @content if defined?(@content)
11
11
  @content = @backend.run_command("cat #{@spath} || echo -n").stdout
12
12
  return @content unless @content.empty?
13
- @content = nil if directory? or size.nil? or size > 0
13
+ @content = nil if directory? || size.nil? || (size > 0)
14
14
  @content
15
15
  end
16
16
  end
@@ -3,28 +3,28 @@
3
3
  # author: Christoph Hartmann
4
4
  # author: Dominik Richter
5
5
 
6
- require 'train/file/remote/unix'
6
+ require "train/file/remote/unix"
7
7
 
8
8
  module Train
9
9
  class File
10
10
  class Remote
11
11
  class Qnx < Train::File::Remote::Unix
12
12
  def content
13
- cat = 'cat'
14
- cat = '/proc/boot/cat' if @backend.os[:release].to_i >= 7
13
+ cat = "cat"
14
+ cat = "/proc/boot/cat" if @backend.os[:release].to_i >= 7
15
15
  @content ||= case
16
16
  when !exist?
17
17
  nil
18
18
  else
19
- @backend.run_command("#{cat} #{@spath}").stdout || ''
19
+ @backend.run_command("#{cat} #{@spath}").stdout || ""
20
20
  end
21
21
  end
22
22
 
23
23
  def type
24
- if @backend.run_command("file #{@spath}").stdout.include?('directory')
25
- return :directory
24
+ if @backend.run_command("file #{@spath}").stdout.include?("directory")
25
+ :directory
26
26
  else
27
- return :file
27
+ :file
28
28
  end
29
29
  end
30
30
 
@@ -32,7 +32,7 @@ module Train
32
32
  mode owner group uid gid mtime size selinux_label link_path mounted stat
33
33
  }.each do |field|
34
34
  define_method field.to_sym do
35
- fail NotImplementedError, "QNX does not implement the #{field}() method yet."
35
+ raise NotImplementedError, "QNX does not implement the #{field}() method yet."
36
36
  end
37
37
  end
38
38
  end
@@ -1,13 +1,9 @@
1
- # encoding: utf-8
2
-
3
- require 'shellwords'
1
+ require "shellwords"
4
2
 
5
3
  module Train
6
4
  class File
7
5
  class Remote
8
6
  class Unix < Train::File::Remote
9
- attr_reader :path
10
-
11
7
  def sanitize_filename(path)
12
8
  @spath = Shellwords.escape(path) || @path
13
9
  end
@@ -16,19 +12,19 @@ module Train
16
12
  @content ||=
17
13
  if !exist? || directory?
18
14
  nil
19
- elsif size.nil? || size.zero?
20
- ''
15
+ elsif size.nil? || size == 0
16
+ ""
21
17
  else
22
- @backend.run_command("cat #{@spath}").stdout || ''
18
+ @backend.run_command("cat #{@spath}").stdout || ""
23
19
  end
24
20
  end
25
21
 
26
22
  def exist?
27
- @exist ||= (
28
- f = @follow_symlink ? '' : " || test -L #{@spath}"
29
- @backend.run_command("test -e #{@spath}"+f)
23
+ @exist ||= begin
24
+ f = @follow_symlink ? "" : " || test -L #{@spath}"
25
+ @backend.run_command("test -e #{@spath}" + f)
30
26
  .exit_status == 0
31
- )
27
+ end
32
28
  end
33
29
 
34
30
  def mounted
@@ -88,14 +84,14 @@ module Train
88
84
  full_path = @backend.run_command("readlink -n #{@spath} -f").stdout
89
85
  # Needed for some OSes like OSX that returns relative path
90
86
  # when the link and target are in the same directory
91
- if !full_path.start_with?('/') && full_path != ''
87
+ if !full_path.start_with?("/") && full_path != ""
92
88
  full_path = ::File.expand_path("../#{full_path}", @spath)
93
89
  end
94
90
  full_path
95
91
  end
96
92
 
97
93
  UNIX_MODE_OWNERS = {
98
- all: 00777,
94
+ all: 00777,
99
95
  owner: 00700,
100
96
  group: 00070,
101
97
  other: 00007,
@@ -10,7 +10,7 @@ module Train
10
10
  def sanitize_filename(path)
11
11
  return if path.nil?
12
12
  # we do not filter :, backslash and forward slash, since they are part of the path
13
- @spath = path.gsub(/[<>"|?*]/, '')
13
+ @spath = path.gsub(/[<>"|?*]/, "")
14
14
  end
15
15
 
16
16
  def basename(suffix = nil, sep = '\\')
@@ -28,7 +28,7 @@ module Train
28
28
  def exist?
29
29
  return @exist if defined?(@exist)
30
30
  @exist = @backend.run_command(
31
- "(Test-Path -Path \"#{@spath}\").ToString()").stdout.chomp == 'True'
31
+ "(Test-Path -Path \"#{@spath}\").ToString()").stdout.chomp == "True"
32
32
  end
33
33
 
34
34
  def owner
@@ -39,11 +39,11 @@ module Train
39
39
  end
40
40
 
41
41
  def type
42
- if attributes.include?('Archive') && !attributes.include?('Directory')
42
+ if attributes.include?("Archive") && !attributes.include?("Directory")
43
43
  return :file
44
- elsif attributes.include?('ReparsePoint')
44
+ elsif attributes.include?("ReparsePoint")
45
45
  return :symlink
46
- elsif attributes.include?('Directory')
46
+ elsif attributes.include?("Directory")
47
47
  return :directory
48
48
  end
49
49
  :unknown
data/lib/train/globals.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Train
2
2
  def self.src_root
3
- File.expand_path(File.join(__FILE__, '..', '..', '..'))
3
+ File.expand_path(File.join(__FILE__, "..", "..", ".."))
4
4
  end
5
5
  end
data/lib/train/options.rb CHANGED
@@ -14,15 +14,15 @@ module Train
14
14
  def option(name, conf = nil, &block)
15
15
  d = conf || {}
16
16
  unless d.is_a? Hash
17
- fail Train::ClientError,
17
+ raise Train::ClientError,
18
18
  "The transport plugin #{self} declared an option #{name} "\
19
19
  "and didn't provide a valid configuration hash."
20
20
  end
21
21
 
22
- if !conf.nil? and !conf[:default].nil? and block_given?
23
- fail Train::ClientError,
22
+ if !conf.nil? && !conf[:default].nil? && block_given?
23
+ raise Train::ClientError,
24
24
  "The transport plugin #{self} declared an option #{name} "\
25
- 'with both a default value and block. Only use one of these.'
25
+ "with both a default value and block. Only use one of these."
26
26
  end
27
27
 
28
28
  d[:default] = block if block_given?
@@ -37,7 +37,7 @@ module Train
37
37
 
38
38
  def include_options(other)
39
39
  unless other.respond_to?(:default_options)
40
- fail "Trying to include options from module #{other.inspect}, "\
40
+ raise "Trying to include options from module #{other.inspect}, "\
41
41
  "which doesn't seem to support options."
42
42
  end
43
43
  default_options.merge!(other.default_options)
@@ -55,7 +55,7 @@ module Train
55
55
  def merge_options(base, opts)
56
56
  res = base.merge(opts || {})
57
57
  default_options.each do |field, hm|
58
- next unless res[field].nil? and hm.key?(:default)
58
+ next unless res[field].nil? && hm.key?(:default)
59
59
  default = hm[:default]
60
60
  if default.is_a? Proc
61
61
  res[field] = default.call(res)
@@ -68,8 +68,8 @@ module Train
68
68
 
69
69
  def validate_options(opts)
70
70
  default_options.each do |field, hm|
71
- if opts[field].nil? and hm[:required]
72
- fail Train::ClientError,
71
+ if opts[field].nil? && hm[:required]
72
+ raise Train::ClientError,
73
73
  "You must provide a value for #{field.to_s.inspect}."
74
74
  end
75
75
  end
@@ -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 "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"
11
11
 
12
12
  module Train::Platforms
13
13
  class << self
@@ -6,7 +6,7 @@ module Train::Platforms
6
6
  # if it does not exist and add a child relationship.
7
7
  def in_family(family)
8
8
  if self.class == Train::Platforms::Family && @name == family
9
- fail "Unable to add family #{@name} to itself: '#{@name}.in_family(#{family})'"
9
+ raise "Unable to add family #{@name} to itself: '#{@name}.in_family(#{family})'"
10
10
  end
11
11
 
12
12
  # add family to the family list
@@ -1,8 +1,6 @@
1
- # encoding: utf-8
2
-
3
- require 'train/platforms/detect/helpers/os_linux'
4
- require 'train/platforms/detect/helpers/os_windows'
5
- require 'rbconfig'
1
+ require "train/platforms/detect/helpers/os_linux"
2
+ require "train/platforms/detect/helpers/os_windows"
3
+ require "rbconfig"
6
4
 
7
5
  module Train::Platforms::Detect::Helpers
8
6
  module OSCommon
@@ -10,11 +8,11 @@ module Train::Platforms::Detect::Helpers
10
8
  include Train::Platforms::Detect::Helpers::Windows
11
9
 
12
10
  def ruby_host_os(regex)
13
- ::RbConfig::CONFIG['host_os'] =~ regex
11
+ ::RbConfig::CONFIG["host_os"] =~ regex
14
12
  end
15
13
 
16
14
  def winrm?
17
- @backend.class.to_s == 'Train::Transports::WinRM::Connection'
15
+ @backend.class.to_s == "Train::Transports::WinRM::Connection"
18
16
  end
19
17
 
20
18
  def unix_file_contents(path)
@@ -23,42 +21,48 @@ module Train::Platforms::Detect::Helpers
23
21
 
24
22
  res = @backend.run_command("test -f #{path} && cat #{path}")
25
23
  # ignore files that can't be read
26
- @files[path] = res.exit_status.zero? ? res.stdout : nil
24
+ @files[path] = res.exit_status == 0 ? res.stdout : nil
27
25
  @files[path]
28
26
  end
29
27
 
30
28
  def unix_file_exist?(path)
31
- @backend.run_command("test -f #{path}").exit_status.zero?
29
+ @backend.run_command("test -f #{path}").exit_status == 0
32
30
  end
33
31
 
34
32
  def command_output(cmd)
35
33
  res = @backend.run_command(cmd).stdout
34
+ # When you try to execute command using ssh connction as root user and you have provided ssh user identity file
35
+ # it gives standard output to login as authorised user other than root. To show this standard ouput as an error
36
+ # to user we are matching the string of stdout and raising the error here so that user gets exact information.
37
+ if @backend.class.to_s == "Train::Transports::SSH::Connection" && res =~ /Please login as the user/
38
+ raise Train::UserError, "SSH failed: #{res}"
39
+ end
36
40
  res.strip! unless res.nil?
37
41
  res
38
42
  end
39
43
 
40
44
  def unix_uname_s
41
45
  return @uname[:s] if @uname.key?(:s)
42
- @uname[:s] = command_output('uname -s')
46
+ @uname[:s] = command_output("uname -s")
43
47
  end
44
48
 
45
49
  def unix_uname_r
46
50
  return @uname[:r] if @uname.key?(:r)
47
- @uname[:r] = command_output('uname -r')
51
+ @uname[:r] = command_output("uname -r")
48
52
  end
49
53
 
50
54
  def unix_uname_m
51
55
  return @uname[:m] if @uname.key?(:m)
52
- @uname[:m] = command_output('uname -m')
56
+ @uname[:m] = command_output("uname -m")
53
57
  end
54
58
 
55
59
  def brocade_version
56
60
  return @cache[:brocade] if @cache.key?(:brocade)
57
- res = command_output('version')
61
+ res = command_output("version")
58
62
 
59
63
  m = res.match(/^Fabric OS:\s+v(\S+)$/)
60
64
  unless m.nil?
61
- return @cache[:brocade] = { version: m[1], type: 'fos' }
65
+ return @cache[:brocade] = { version: m[1], type: "fos" }
62
66
  end
63
67
 
64
68
  @cache[:brocade] = nil
@@ -66,53 +70,53 @@ module Train::Platforms::Detect::Helpers
66
70
 
67
71
  def cisco_show_version
68
72
  return @cache[:cisco] if @cache.key?(:cisco)
69
- res = command_output('show version')
73
+ res = command_output("show version")
70
74
 
71
75
  m = res.match(/Cisco IOS Software, [^,]+? \(([^,]+?)\), Version (\d+\.\d+)/)
72
76
  unless m.nil?
73
- return @cache[:cisco] = { version: m[2], model: m[1], type: 'ios' }
77
+ return @cache[:cisco] = { version: m[2], model: m[1], type: "ios" }
74
78
  end
75
79
 
76
80
  m = res.match(/Cisco IOS Software, IOS-XE Software, [^,]+? \(([^,]+?)\), Version (\d+\.\d+\.\d+[A-Z]*)/)
77
81
  unless m.nil?
78
- return @cache[:cisco] = { version: m[2], model: m[1], type: 'ios-xe' }
82
+ return @cache[:cisco] = { version: m[2], model: m[1], type: "ios-xe" }
79
83
  end
80
84
 
81
85
  m = res.match(/Cisco Nexus Operating System \(NX-OS\) Software/)
82
86
  unless m.nil?
83
87
  v = res[/^\s*system:\s+version (\d+\.\d+)/, 1]
84
- return @cache[:cisco] = { version: v, type: 'nexus' }
88
+ return @cache[:cisco] = { version: v, type: "nexus" }
85
89
  end
86
90
 
87
91
  @cache[:cisco] = nil
88
92
  end
89
93
 
90
94
  def unix_uuid
91
- uuid = unix_uuid_from_chef
92
- uuid = unix_uuid_from_machine_file if uuid.nil?
93
- uuid = uuid_from_command if uuid.nil?
94
- raise Train::TransportError, 'Cannot find a UUID for your node.' if uuid.nil?
95
- uuid
95
+ (unix_uuid_from_chef ||
96
+ unix_uuid_from_machine_file ||
97
+ uuid_from_command ||
98
+ raise(Train::TransportError, "Cannot find a UUID for your node."))
96
99
  end
97
100
 
98
101
  def unix_uuid_from_chef
99
- file = @backend.file('/var/chef/cache/data_collector_metadata.json')
100
- if file.exist? && !file.size.zero?
102
+ file = @backend.file("/var/chef/cache/data_collector_metadata.json")
103
+ if file.exist? && file.size != 0
101
104
  json = ::JSON.parse(file.content)
102
- return json['node_uuid'] if json['node_uuid']
105
+ return json["node_uuid"] if json["node_uuid"]
103
106
  end
104
107
  end
105
108
 
106
109
  def unix_uuid_from_machine_file
107
- %W(
110
+ # require 'pry';binding.pry
111
+ %W{
108
112
  /etc/chef/chef_guid
109
113
  #{ENV['HOME']}/.chef/chef_guid
110
114
  /etc/machine-id
111
115
  /var/lib/dbus/machine-id
112
116
  /var/db/dbus/machine-id
113
- ).each do |path|
117
+ }.each do |path|
114
118
  file = @backend.file(path)
115
- next unless file.exist? && !file.size.zero?
119
+ next unless file.exist? && file.size != 0
116
120
  return file.content.chomp if path =~ /guid/
117
121
  return uuid_from_string(file.content.chomp)
118
122
  end
@@ -125,7 +129,7 @@ module Train::Platforms::Detect::Helpers
125
129
  def uuid_from_command
126
130
  return unless @platform[:uuid_command]
127
131
  result = @backend.run_command(@platform[:uuid_command])
128
- uuid_from_string(result.stdout.chomp) if result.exit_status.zero? && !result.stdout.empty?
132
+ uuid_from_string(result.stdout.chomp) if result.exit_status == 0 && !result.stdout.empty?
129
133
  end
130
134
 
131
135
  # This hashes the passed string into SHA1.
@@ -134,11 +138,11 @@ module Train::Platforms::Detect::Helpers
134
138
  def uuid_from_string(string)
135
139
  hash = Digest::SHA1.new
136
140
  hash.update(string)
137
- ary = hash.digest.unpack('NnnnnN')
141
+ ary = hash.digest.unpack("NnnnnN")
138
142
  ary[2] = (ary[2] & 0x0FFF) | (5 << 12)
139
143
  ary[3] = (ary[3] & 0x3FFF) | 0x8000
140
144
  # rubocop:disable Style/FormatString
141
- '%08x-%04x-%04x-%04x-%04x%08x' % ary
145
+ "%08x-%04x-%04x-%04x-%04x%08x" % ary
142
146
  end
143
147
  end
144
148
  end