train 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.
- checksums.yaml +4 -4
- data/lib/train.rb +20 -20
- data/lib/train/errors.rb +1 -1
- data/lib/train/extras.rb +2 -2
- data/lib/train/extras/command_wrapper.rb +24 -24
- data/lib/train/extras/stat.rb +27 -27
- data/lib/train/file.rb +30 -30
- data/lib/train/file/local.rb +8 -8
- data/lib/train/file/local/unix.rb +5 -5
- data/lib/train/file/local/windows.rb +1 -1
- data/lib/train/file/remote.rb +8 -8
- data/lib/train/file/remote/aix.rb +1 -1
- data/lib/train/file/remote/linux.rb +2 -2
- data/lib/train/file/remote/qnx.rb +8 -8
- data/lib/train/file/remote/unix.rb +10 -14
- data/lib/train/file/remote/windows.rb +5 -5
- data/lib/train/globals.rb +1 -1
- data/lib/train/options.rb +8 -8
- data/lib/train/platforms.rb +8 -8
- data/lib/train/platforms/common.rb +1 -1
- data/lib/train/platforms/detect/helpers/os_common.rb +36 -32
- data/lib/train/platforms/detect/helpers/os_linux.rb +12 -12
- data/lib/train/platforms/detect/helpers/os_windows.rb +27 -29
- data/lib/train/platforms/detect/scanner.rb +4 -4
- data/lib/train/platforms/detect/specifications/api.rb +8 -8
- data/lib/train/platforms/detect/specifications/os.rb +252 -252
- data/lib/train/platforms/detect/uuid.rb +5 -7
- data/lib/train/platforms/platform.rb +9 -5
- data/lib/train/plugin_test_helper.rb +12 -12
- data/lib/train/plugins.rb +5 -5
- data/lib/train/plugins/base_connection.rb +13 -13
- data/lib/train/plugins/transport.rb +7 -7
- data/lib/train/transports/azure.rb +23 -23
- data/lib/train/transports/cisco_ios_connection.rb +20 -20
- data/lib/train/transports/clients/azure/graph_rbac.rb +2 -2
- data/lib/train/transports/clients/azure/vault.rb +4 -4
- data/lib/train/transports/docker.rb +4 -10
- data/lib/train/transports/gcp.rb +23 -23
- data/lib/train/transports/helpers/azure/file_credentials.rb +8 -8
- data/lib/train/transports/helpers/azure/file_parser.rb +1 -1
- data/lib/train/transports/helpers/azure/subscription_number_file_parser.rb +1 -1
- data/lib/train/transports/local.rb +22 -22
- data/lib/train/transports/mock.rb +33 -35
- data/lib/train/transports/ssh.rb +47 -47
- data/lib/train/transports/ssh_connection.rb +28 -28
- data/lib/train/transports/vmware.rb +32 -34
- data/lib/train/transports/winrm.rb +37 -37
- data/lib/train/transports/winrm_connection.rb +12 -12
- data/lib/train/version.rb +1 -1
- metadata +2 -2
data/lib/train/file/local.rb
CHANGED
@@ -12,7 +12,7 @@ module Train
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def content
|
15
|
-
@content ||= ::File.read(@path, encoding:
|
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
|
45
|
+
when "blockSpecial"
|
46
46
|
:block_device
|
47
|
-
when
|
47
|
+
when "characterSpecial"
|
48
48
|
:character_device
|
49
|
-
when
|
49
|
+
when "link"
|
50
50
|
:symlink
|
51
|
-
when
|
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
|
80
|
-
require
|
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
|
4
|
-
require
|
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 ?
|
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:
|
82
|
+
all: 00777,
|
83
83
|
owner: 00700,
|
84
84
|
group: 00070,
|
85
85
|
other: 00007,
|
data/lib/train/file/remote.rb
CHANGED
@@ -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
|
-
|
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
|
33
|
-
require
|
34
|
-
require
|
35
|
-
require
|
36
|
-
require
|
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
|
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?
|
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
|
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 =
|
14
|
-
cat =
|
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?(
|
25
|
-
|
24
|
+
if @backend.run_command("file #{@spath}").stdout.include?("directory")
|
25
|
+
:directory
|
26
26
|
else
|
27
|
-
|
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
|
-
|
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
|
-
|
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
|
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 ?
|
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?(
|
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:
|
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 ==
|
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?(
|
42
|
+
if attributes.include?("Archive") && !attributes.include?("Directory")
|
43
43
|
return :file
|
44
|
-
elsif attributes.include?(
|
44
|
+
elsif attributes.include?("ReparsePoint")
|
45
45
|
return :symlink
|
46
|
-
elsif attributes.include?(
|
46
|
+
elsif attributes.include?("Directory")
|
47
47
|
return :directory
|
48
48
|
end
|
49
49
|
:unknown
|
data/lib/train/globals.rb
CHANGED
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
|
-
|
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?
|
23
|
-
|
22
|
+
if !conf.nil? && !conf[:default].nil? && block_given?
|
23
|
+
raise Train::ClientError,
|
24
24
|
"The transport plugin #{self} declared an option #{name} "\
|
25
|
-
|
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
|
-
|
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?
|
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?
|
72
|
-
|
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
|
data/lib/train/platforms.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
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
|
-
|
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
|
-
|
2
|
-
|
3
|
-
require
|
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[
|
11
|
+
::RbConfig::CONFIG["host_os"] =~ regex
|
14
12
|
end
|
15
13
|
|
16
14
|
def winrm?
|
17
|
-
@backend.class.to_s ==
|
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
|
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
|
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(
|
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(
|
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(
|
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(
|
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:
|
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(
|
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:
|
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:
|
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:
|
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
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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(
|
100
|
-
if file.exist? &&
|
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[
|
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
|
-
|
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
|
-
|
117
|
+
}.each do |path|
|
114
118
|
file = @backend.file(path)
|
115
|
-
next unless file.exist? &&
|
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
|
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(
|
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
|
-
|
145
|
+
"%08x-%04x-%04x-%04x-%04x%08x" % ary
|
142
146
|
end
|
143
147
|
end
|
144
148
|
end
|