train-core 3.2.14 → 3.2.20
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 +16 -16
- data/lib/train/platforms/common.rb +13 -10
- data/lib/train/platforms/detect/helpers/os_common.rb +20 -4
- data/lib/train/platforms/detect/helpers/os_linux.rb +7 -0
- data/lib/train/platforms/detect/helpers/os_windows.rb +5 -0
- data/lib/train/platforms/detect/scanner.rb +2 -2
- data/lib/train/platforms/detect/specifications/os.rb +416 -526
- data/lib/train/plugins/base_connection.rb +5 -1
- data/lib/train/version.rb +1 -1
- metadata +42 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebf0e0aa7d97a1c6b4f63c707bba2daf62b2fa53df072dc0884c727dfff1016d
|
4
|
+
data.tar.gz: 345f982e6e7966172ba88817689a73ac021cd692d97f9d4ae13f6b772d987c13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5884539b913f79cdc135a05f6e4ed47ddd5bd051ad919977804adcc9e36e2ddbd85bda8dec3185be32cd2de1d1027628d755c5188728ee524e567bc914713116
|
7
|
+
data.tar.gz: a061b7dc4e62f0722a2720e13e0634e077565b6dbd52adc1c56a002e2c58c395dbc8c6cb44a9bb033cab14a186883332b35d23ed9efd5941bb657481c2c9a006
|
data/lib/train.rb
CHANGED
@@ -7,7 +7,7 @@ require_relative "train/options"
|
|
7
7
|
require_relative "train/plugins"
|
8
8
|
require_relative "train/errors"
|
9
9
|
require_relative "train/platforms"
|
10
|
-
require "uri"
|
10
|
+
require "addressable/uri"
|
11
11
|
|
12
12
|
module Train
|
13
13
|
# Create a new transport instance, with the plugin indicated by the
|
@@ -101,7 +101,7 @@ module Train
|
|
101
101
|
creds[:path] ||= uri.path
|
102
102
|
creds[:password] ||=
|
103
103
|
if opts[:www_form_encoded_password] && !uri.password.nil?
|
104
|
-
URI.
|
104
|
+
Addressable::URI.unencode_component(uri.password)
|
105
105
|
else
|
106
106
|
uri.password
|
107
107
|
end
|
@@ -121,24 +121,24 @@ module Train
|
|
121
121
|
# Parse a URI. Supports empty URI's with paths, e.g. `mock://`
|
122
122
|
#
|
123
123
|
# @param string [string] URI string, e.g. `schema://domain.com`
|
124
|
-
# @return [URI
|
124
|
+
# @return [Addressable::URI] parsed URI object
|
125
125
|
def self.parse_uri(string)
|
126
|
-
URI.parse(string)
|
127
|
-
rescue URI::InvalidURIError => e
|
126
|
+
u = Addressable::URI.parse(string)
|
128
127
|
# A use-case we want to catch is parsing empty URIs with a schema
|
129
128
|
# e.g. mock://. To do this, we match it manually and fake the hostname
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
129
|
+
if u.scheme && (u.host.nil? || u.host.empty?) && u.path.empty?
|
130
|
+
case string
|
131
|
+
when %r{^([a-z]+)://$}
|
132
|
+
string += "dummy"
|
133
|
+
when /^([a-z]+):$/
|
134
|
+
string += "//dummy"
|
135
|
+
end
|
136
|
+
u = Addressable::URI.parse(string)
|
137
|
+
u.host = nil
|
137
138
|
end
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
uri
|
139
|
+
u
|
140
|
+
rescue Addressable::URI::InvalidURIError => e
|
141
|
+
raise Train::UserError, e
|
142
142
|
end
|
143
143
|
private_class_method :parse_uri
|
144
144
|
|
@@ -19,16 +19,19 @@ module Train::Platforms
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def detect(&block)
|
22
|
-
if
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
@detect = block if block
|
23
|
+
|
24
|
+
# TODO: detect shouldn't be a setter and getter at the same time
|
25
|
+
@detect ||= ->(_) { false }
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
be = backend ? backend.backend_type : "unknown"
|
30
|
+
"%s:%s:%s" % [self.class, be, name]
|
31
|
+
end
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
to_s
|
32
35
|
end
|
33
36
|
end
|
34
37
|
end
|
@@ -70,11 +70,8 @@ module Train::Platforms::Detect::Helpers
|
|
70
70
|
res = command_output("version")
|
71
71
|
|
72
72
|
m = res.match(/^Fabric OS:\s+v(\S+)$/)
|
73
|
-
unless m.nil?
|
74
|
-
return @cache[:brocade] = { version: m[1], type: "fos" }
|
75
|
-
end
|
76
73
|
|
77
|
-
@cache[:brocade] =
|
74
|
+
@cache[:brocade] = m && { version: m[1], type: "fos" }
|
78
75
|
end
|
79
76
|
|
80
77
|
def cisco_show_version
|
@@ -156,5 +153,24 @@ module Train::Platforms::Detect::Helpers
|
|
156
153
|
# rubocop:disable Style/FormatString
|
157
154
|
"%08x-%04x-%04x-%04x-%04x%08x" % ary
|
158
155
|
end
|
156
|
+
|
157
|
+
def json_cmd(cmd)
|
158
|
+
cmd = @backend.run_command(cmd)
|
159
|
+
if cmd.exit_status == 0 && !cmd.stdout.empty?
|
160
|
+
require "json"
|
161
|
+
eos_ver = JSON.parse(cmd.stdout)
|
162
|
+
@platform[:release] = eos_ver["version"]
|
163
|
+
@platform[:arch] = eos_ver["architecture"]
|
164
|
+
true
|
165
|
+
end
|
166
|
+
rescue JSON::ParserError
|
167
|
+
nil
|
168
|
+
end
|
169
|
+
|
170
|
+
def set_from_uname
|
171
|
+
@platform[:name] = unix_uname_s.lines.first.chomp
|
172
|
+
@platform[:release] = unix_uname_r.lines.first.chomp
|
173
|
+
true
|
174
|
+
end
|
159
175
|
end
|
160
176
|
end
|
@@ -19,6 +19,13 @@ module Train::Platforms::Detect::Helpers
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
def redhatish(path)
|
23
|
+
if (raw = unix_file_contents(path))
|
24
|
+
@platform[:release] = redhatish_version(raw)
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
22
29
|
def linux_os_release
|
23
30
|
data = unix_file_contents("/etc/os-release")
|
24
31
|
return if data.nil?
|
@@ -44,6 +44,11 @@ module Train::Platforms::Detect::Helpers
|
|
44
44
|
true
|
45
45
|
end
|
46
46
|
|
47
|
+
def local_windows?
|
48
|
+
@backend.class.to_s == "Train::Transports::Local::Connection" &&
|
49
|
+
ruby_host_os(/mswin|mingw32|windows/)
|
50
|
+
end
|
51
|
+
|
47
52
|
# reads os name and version from wmic
|
48
53
|
# @see https://msdn.microsoft.com/en-us/library/bb742610.aspx#EEAA
|
49
54
|
# Thanks to Matt Wrock (https://github.com/mwrock) for this hint
|
@@ -27,7 +27,7 @@ module Train::Platforms::Detect
|
|
27
27
|
top.each do |_name, plat|
|
28
28
|
# we are doing a instance_eval here to make sure we have the proper
|
29
29
|
# context with all the detect helper methods
|
30
|
-
next unless instance_eval(&plat.detect)
|
30
|
+
next unless instance_eval(&plat.detect)
|
31
31
|
|
32
32
|
# if we have a match start looking at the children
|
33
33
|
plat_result = scan_children(plat)
|
@@ -43,7 +43,7 @@ module Train::Platforms::Detect
|
|
43
43
|
|
44
44
|
def scan_children(parent)
|
45
45
|
parent.children.each do |plat, condition|
|
46
|
-
next unless instance_eval(&plat.detect)
|
46
|
+
next unless instance_eval(&plat.detect)
|
47
47
|
|
48
48
|
if plat.class == Train::Platforms::Platform
|
49
49
|
return plat if condition.empty? || check_condition(condition)
|
@@ -1,629 +1,519 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# rubocop:disable Style/Next
|
4
|
-
# rubocop:disable Metrics/AbcSize
|
5
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
6
|
-
# rubocop:disable Metrics/ClassLength
|
7
|
-
# rubocop:disable Metrics/MethodLength
|
8
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
1
|
+
# rubocop:disable Style/ParenthesesAroundCondition
|
9
2
|
|
10
3
|
module Train::Platforms::Detect::Specifications
|
11
4
|
class OS
|
12
5
|
def self.load
|
13
|
-
|
6
|
+
load_toplevel
|
7
|
+
load_windows
|
8
|
+
load_unix
|
9
|
+
load_other
|
10
|
+
end
|
14
11
|
|
15
|
-
|
12
|
+
def self.load_toplevel
|
16
13
|
plat.family("os").detect { true }
|
14
|
+
end
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
if @backend.class.to_s == "Train::Transports::Local::Connection"
|
25
|
-
is_windows = true if ruby_host_os(/mswin|mingw32|windows/)
|
26
|
-
end
|
16
|
+
def self.load_windows
|
17
|
+
declare_category("windows", "os") do
|
18
|
+
(winrm? ||
|
19
|
+
local_windows? ||
|
20
|
+
detect_windows) # ssh
|
21
|
+
end
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
declare_family("windows", "windows") do
|
24
|
+
detect_windows
|
25
|
+
end
|
26
|
+
end
|
32
27
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
28
|
+
def self.load_unix
|
29
|
+
declare_category("unix", "os") do
|
30
|
+
# we want to catch a special case here where cisco commands
|
31
|
+
# don't return an exit status and still print to stdout
|
32
|
+
uname = unix_uname_s
|
33
|
+
unless (uname.empty? ||
|
34
|
+
uname.start_with?("Line has invalid autocommand") ||
|
35
|
+
uname.start_with?("The command you have entered"))
|
36
|
+
@platform[:arch] = unix_uname_m
|
37
|
+
true
|
39
38
|
end
|
39
|
+
end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
# don't return an exit status and still print to stdout
|
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
|
-
@platform[:arch] = unix_uname_m
|
48
|
-
true
|
49
|
-
end
|
50
|
-
end
|
41
|
+
load_linux
|
42
|
+
load_other_unix
|
43
|
+
load_bsd
|
44
|
+
end
|
51
45
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
46
|
+
def self.load_linux
|
47
|
+
declare_category("linux", "unix") do
|
48
|
+
unix_uname_s =~ /linux/i
|
49
|
+
end
|
57
50
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
true unless unix_file_contents("/etc/debian_version").nil?
|
62
|
-
end
|
63
|
-
plat.name("ubuntu").title("Ubuntu Linux").in_family("debian")
|
64
|
-
.detect do
|
65
|
-
lsb = read_linux_lsb
|
66
|
-
if lsb && lsb[:id] =~ /ubuntu/i
|
67
|
-
@platform[:release] = lsb[:release]
|
68
|
-
true
|
69
|
-
end
|
70
|
-
end
|
71
|
-
plat.name("linuxmint").title("LinuxMint").in_family("debian")
|
72
|
-
.detect do
|
73
|
-
lsb = read_linux_lsb
|
74
|
-
if lsb && lsb[:id] =~ /linuxmint/i
|
75
|
-
@platform[:release] = lsb[:release]
|
76
|
-
true
|
77
|
-
end
|
78
|
-
end
|
79
|
-
plat.name("raspbian").title("Raspbian Linux").in_family("debian")
|
80
|
-
.detect do
|
81
|
-
if (linux_os_release && linux_os_release["NAME"] =~ /raspbian/i) || \
|
82
|
-
unix_file_exist?("/usr/bin/raspi-config")
|
83
|
-
@platform[:release] = unix_file_contents("/etc/debian_version").chomp
|
84
|
-
true
|
85
|
-
end
|
86
|
-
end
|
87
|
-
plat.name("debian").title("Debian Linux").in_family("debian")
|
88
|
-
.detect do
|
89
|
-
lsb = read_linux_lsb
|
90
|
-
if lsb && lsb[:id] =~ /debian/i
|
91
|
-
@platform[:release] = lsb[:release]
|
92
|
-
true
|
93
|
-
end
|
51
|
+
declare_category("debian", "linux") do
|
52
|
+
unix_file_exist?("/etc/debian_version")
|
53
|
+
end
|
94
54
|
|
95
|
-
|
96
|
-
|
55
|
+
declare_lsb("ubuntu", "Ubuntu Linux", "debian", /ubuntu/i)
|
56
|
+
|
57
|
+
declare_lsb("linuxmint", "LinuxMint", "debian", /linuxmint/i)
|
58
|
+
|
59
|
+
declare_instance("kali", "Kali Linux", "debian") do
|
60
|
+
l_o_r = linux_os_release
|
61
|
+
if l_o_r && l_o_r["ID"] == "kali"
|
62
|
+
@platform[:release] = l_o_r["VERSION"]
|
97
63
|
true
|
98
64
|
end
|
65
|
+
end
|
66
|
+
|
67
|
+
declare_instance("raspbian", "Raspbian Linux", "debian") do
|
68
|
+
rel = linux_os_release
|
69
|
+
if (rel && rel["NAME"] =~ /raspbian/i) ||
|
70
|
+
unix_file_exist?("/usr/bin/raspi-config")
|
71
|
+
@platform[:release] = unix_file_contents("/etc/debian_version").chomp
|
99
72
|
|
100
|
-
# fedora family
|
101
|
-
plat.family("fedora").in_family("linux")
|
102
|
-
.detect do
|
103
|
-
true if linux_os_release && linux_os_release["NAME"] =~ /fedora/i
|
104
|
-
end
|
105
|
-
plat.name("fedora").title("Fedora").in_family("fedora")
|
106
|
-
.detect do
|
107
|
-
@platform[:release] = linux_os_release["VERSION_ID"]
|
108
73
|
true
|
109
74
|
end
|
75
|
+
end
|
76
|
+
|
77
|
+
declare_instance("debian", "Debian Linux", "debian") do
|
78
|
+
# if we get this far we have to be some type of debian
|
79
|
+
@platform[:release] = unix_file_contents("/etc/debian_version").chomp
|
80
|
+
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
declare_category("fedora", "linux") do
|
85
|
+
rel = linux_os_release
|
86
|
+
rel && rel["NAME"] =~ /fedora/i
|
87
|
+
end
|
88
|
+
|
89
|
+
declare_instance("fedora", "Fedora", "fedora") do
|
90
|
+
@platform[:release] = linux_os_release["VERSION_ID"]
|
91
|
+
true
|
92
|
+
end
|
110
93
|
|
111
|
-
# arista_eos family
|
112
|
-
# this checks for the arista bash shell
|
113
94
|
# must come before redhat as it uses fedora under the hood
|
114
95
|
plat.family("arista_eos").title("Arista EOS Family").in_family("linux")
|
115
96
|
.detect do
|
116
97
|
true
|
117
98
|
end
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
begin
|
125
|
-
eos_ver = JSON.parse(cmd.stdout)
|
126
|
-
@platform[:release] = eos_ver["version"]
|
127
|
-
@platform[:arch] = eos_ver["architecture"]
|
128
|
-
true
|
129
|
-
rescue JSON::ParserError
|
130
|
-
nil
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
99
|
+
|
100
|
+
declare_instance("arista_eos_bash", "Arista EOS Bash Shell", "arista_eos") do
|
101
|
+
# this checks for the arista bash shell
|
102
|
+
if unix_file_exist?("/usr/bin/FastCli")
|
103
|
+
# TODO: no tests
|
104
|
+
json_cmd('FastCli -p 15 -c "show version | json"')
|
134
105
|
end
|
106
|
+
end
|
135
107
|
|
136
|
-
|
137
|
-
|
138
|
-
|
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?
|
108
|
+
declare_category("redhat", "linux") do
|
109
|
+
true
|
110
|
+
end
|
142
111
|
|
112
|
+
declare_instance("centos", "Centos Linux", "redhat") do
|
113
|
+
lsb = read_linux_lsb
|
114
|
+
if lsb && lsb[:id] =~ /centos/i
|
115
|
+
# TODO: no tests
|
116
|
+
@platform[:release] = lsb[:release]
|
117
|
+
true
|
118
|
+
elsif (rel = linux_os_release) && rel["NAME"] =~ /centos/i
|
119
|
+
@platform[:release] = redhatish_version(unix_file_contents("/etc/redhat-release"))
|
143
120
|
true
|
144
121
|
end
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
@platform[:release] = redhatish_version(raw)
|
163
|
-
true
|
164
|
-
end
|
165
|
-
end
|
166
|
-
plat.name("scientific").title("Scientific Linux").in_family("redhat")
|
167
|
-
.detect do
|
168
|
-
lsb = read_linux_lsb
|
169
|
-
if lsb && lsb[:id] =~ /scientific/i
|
170
|
-
@platform[:release] = lsb[:release]
|
171
|
-
true
|
172
|
-
end
|
173
|
-
end
|
174
|
-
plat.name("xenserver").title("Xenserer Linux").in_family("redhat")
|
175
|
-
.detect do
|
176
|
-
lsb = read_linux_lsb
|
177
|
-
if lsb && lsb[:id] =~ /xenserver/i
|
178
|
-
@platform[:release] = lsb[:release]
|
179
|
-
true
|
180
|
-
end
|
181
|
-
end
|
182
|
-
plat.name("parallels-release").title("Parallels Linux").in_family("redhat")
|
183
|
-
.detect do
|
184
|
-
unless (raw = unix_file_contents("/etc/parallels-release")).nil?
|
185
|
-
@platform[:name] = redhatish_platform(raw)
|
186
|
-
@platform[:release] = raw[/(\d\.\d\.\d)/, 1]
|
187
|
-
true
|
188
|
-
end
|
189
|
-
end
|
190
|
-
plat.name("wrlinux").title("Wind River Linux").in_family("redhat")
|
191
|
-
.detect do
|
192
|
-
if linux_os_release && linux_os_release["ID_LIKE"] =~ /wrlinux/i
|
193
|
-
@platform[:release] = linux_os_release["VERSION"]
|
194
|
-
true
|
195
|
-
end
|
196
|
-
end
|
197
|
-
plat.name("amazon").title("Amazon Linux").in_family("redhat")
|
198
|
-
.detect do
|
199
|
-
lsb = read_linux_lsb
|
200
|
-
if lsb && lsb[:id] =~ /amazon/i
|
201
|
-
@platform[:release] = lsb[:release]
|
202
|
-
true
|
203
|
-
elsif (raw = unix_file_contents("/etc/system-release")) =~ /amazon/i
|
204
|
-
@platform[:name] = redhatish_platform(raw)
|
205
|
-
@platform[:release] = redhatish_version(raw)
|
206
|
-
true
|
207
|
-
end
|
122
|
+
end
|
123
|
+
|
124
|
+
declare_instance("oracle", "Oracle Linux", "redhat") do
|
125
|
+
(redhatish("/etc/oracle-release") ||
|
126
|
+
redhatish("/etc/enterprise-release"))
|
127
|
+
end
|
128
|
+
|
129
|
+
declare_lsb("scientific", "Scientific Linux", "redhat", /scientific/i)
|
130
|
+
|
131
|
+
declare_lsb("xenserver", "Xenserer Linux", "redhat", /xenserver/i)
|
132
|
+
|
133
|
+
declare_instance("parallels-release", "Parallels Linux", "redhat") do
|
134
|
+
if (raw = unix_file_contents("/etc/parallels-release"))
|
135
|
+
@platform[:name] = redhatish_platform(raw)
|
136
|
+
@platform[:release] = raw[/(\d\.\d\.\d)/, 1]
|
137
|
+
# TODO: no tests
|
138
|
+
true
|
208
139
|
end
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
@platform[:name] = redhatish_platform(raw)
|
217
|
-
@platform[:release] = redhatish_version(raw)
|
218
|
-
true
|
219
|
-
end
|
140
|
+
end
|
141
|
+
|
142
|
+
declare_instance("wrlinux", "Wind River Linux", "redhat") do
|
143
|
+
rel = linux_os_release
|
144
|
+
if rel && rel["ID_LIKE"] =~ /wrlinux/i
|
145
|
+
@platform[:release] = rel["VERSION"]
|
146
|
+
true
|
220
147
|
end
|
148
|
+
end
|
149
|
+
|
150
|
+
declare_lsb_or_content("amazon", "Amazon Linux", "redhat", "/etc/system-release", /amazon/i)
|
151
|
+
|
152
|
+
declare_lsb_or_content("cloudlinux", "CloudLinux", "redhat", "/etc/redhat-release", /cloudlinux/i)
|
153
|
+
|
221
154
|
# keep redhat at the end as a fallback for anything with a redhat-release
|
222
|
-
|
223
|
-
.detect do
|
224
|
-
lsb = read_linux_lsb
|
225
|
-
if lsb && lsb[:id] =~ /redhat/i
|
226
|
-
@platform[:release] = lsb[:release]
|
227
|
-
true
|
228
|
-
elsif !(raw = unix_file_contents("/etc/redhat-release")).nil?
|
229
|
-
# must be some type of redhat
|
230
|
-
@platform[:name] = redhatish_platform(raw)
|
231
|
-
@platform[:release] = redhatish_version(raw)
|
232
|
-
true
|
233
|
-
end
|
234
|
-
end
|
155
|
+
declare_lsb_or_content("redhat", "Red Hat Linux", "redhat", "/etc/redhat-release", /redhat/i, /./)
|
235
156
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
true
|
249
|
-
end
|
250
|
-
end
|
251
|
-
plat.name("opensuse").title("OpenSUSE Linux").in_family("suse")
|
252
|
-
.detect do
|
253
|
-
true if (linux_os_release && linux_os_release["NAME"] =~ /^opensuse/i) ||
|
254
|
-
unix_file_contents("/etc/SuSE-release") =~ /^opensuse/i
|
255
|
-
end
|
256
|
-
plat.name("suse").title("Suse Linux").in_family("suse")
|
257
|
-
.detect do
|
258
|
-
true if (linux_os_release && linux_os_release["NAME"] =~ /^sles/i) ||
|
259
|
-
unix_file_contents("/etc/SuSE-release") =~ /suse/i
|
157
|
+
declare_category("suse", "linux") do
|
158
|
+
rel = linux_os_release
|
159
|
+
if rel && rel["ID_LIKE"] =~ /suse/i
|
160
|
+
@platform[:release] = rel["VERSION"]
|
161
|
+
true
|
162
|
+
elsif (suse = unix_file_contents("/etc/SuSE-release"))
|
163
|
+
# https://rubular.com/r/UKaYWolCYFMfp1
|
164
|
+
version = suse.scan(/VERSION = (\d+)\nPATCHLEVEL = (\d+)/).flatten.join(".")
|
165
|
+
# https://rubular.com/r/b5PN3hZDxa5amV
|
166
|
+
version = suse[/VERSION\s?=\s?"?([\d\.]{2,})"?/, 1] if version == ""
|
167
|
+
@platform[:release] = version
|
168
|
+
true
|
260
169
|
end
|
170
|
+
end
|
261
171
|
|
262
|
-
|
263
|
-
plat.name("arch").title("Arch Linux").in_family("linux")
|
264
|
-
.detect do
|
265
|
-
unless unix_file_contents("/etc/arch-release").nil?
|
266
|
-
# Because this is a rolling release distribution,
|
267
|
-
# use the kernel release, ex. 4.1.6-1-ARCH
|
268
|
-
@platform[:release] = unix_uname_r
|
269
|
-
true
|
270
|
-
end
|
271
|
-
end
|
172
|
+
declare_os_or_file("opensuse", "OpenSUSE Linux", "suse", "/etc/SuSE-release", /^opensuse/i)
|
272
173
|
|
273
|
-
|
274
|
-
plat.name("slackware").title("Slackware Linux").in_family("linux")
|
275
|
-
.detect do
|
276
|
-
unless (raw = unix_file_contents("/etc/slackware-version")).nil?
|
277
|
-
@platform[:release] = raw.scan(/(\d+|\.+)/).join
|
278
|
-
true
|
279
|
-
end
|
280
|
-
end
|
174
|
+
declare_os_or_file("suse", "Suse Linux", "suse", "/etc/SuSE-release", /^sles/i, /suse/i)
|
281
175
|
|
282
|
-
|
283
|
-
plat.name("gentoo").title("Gentoo Linux").in_family("linux")
|
284
|
-
.detect do
|
285
|
-
unless (raw = unix_file_contents("/etc/gentoo-release")).nil?
|
286
|
-
@platform[:release] = raw.scan(/(\d+|\.+)/).join
|
287
|
-
true
|
288
|
-
end
|
289
|
-
end
|
176
|
+
declare_path_and_uname("arch", "Arch Linux", "linux", "/etc/arch-release")
|
290
177
|
|
291
|
-
|
292
|
-
plat.name("exherbo").title("Exherbo Linux").in_family("linux")
|
293
|
-
.detect do
|
294
|
-
unless unix_file_contents("/etc/exherbo-release").nil?
|
295
|
-
# Because this is a rolling release distribution,
|
296
|
-
# use the kernel release, ex. 4.1.6
|
297
|
-
@platform[:release] = unix_uname_r
|
298
|
-
true
|
299
|
-
end
|
300
|
-
end
|
178
|
+
declare_file_content("slackware", "Slackware Linux", "linux", "/etc/slackware-version")
|
301
179
|
|
302
|
-
|
303
|
-
plat.name("alpine").title("Alpine Linux").in_family("linux")
|
304
|
-
.detect do
|
305
|
-
unless (raw = unix_file_contents("/etc/alpine-release")).nil?
|
306
|
-
@platform[:release] = raw.strip
|
307
|
-
true
|
308
|
-
end
|
309
|
-
end
|
180
|
+
declare_file_content("gentoo", "Gentoo Linux", "linux", "/etc/gentoo-release")
|
310
181
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
182
|
+
declare_path_and_uname("exherbo", "Exherbo Linux", "linux", "/etc/exherbo-release")
|
183
|
+
|
184
|
+
# TODO: try using declare_path
|
185
|
+
declare_instance("alpine", "Alpine Linux", "linux") do
|
186
|
+
if (raw = unix_file_contents("/etc/alpine-release"))
|
187
|
+
@platform[:release] = raw.strip
|
188
|
+
# TODO: no tests
|
189
|
+
true
|
319
190
|
end
|
191
|
+
end
|
320
192
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
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
|
193
|
+
declare_instance("coreos", "CoreOS Linux", "linux") do
|
194
|
+
if unix_file_exist?("/etc/coreos/update.conf")
|
195
|
+
lsb = read_linux_lsb
|
196
|
+
@platform[:release] = lsb[:release]
|
197
|
+
true
|
331
198
|
end
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
199
|
+
end
|
200
|
+
|
201
|
+
declare_category("yocto", "linux") do
|
202
|
+
# /etc/issue isn't specific to yocto, but it's the only way to detect
|
203
|
+
# the platform because there are no other identifying files
|
204
|
+
issue = unix_file_contents("/etc/issue")
|
205
|
+
|
206
|
+
issue && issue.match?(/Poky|balenaOS/)
|
207
|
+
end
|
208
|
+
|
209
|
+
declare_instance("yocto", "Yocto Project Linux", "yocto") do
|
210
|
+
issue = unix_file_contents("/etc/issue")
|
211
|
+
if issue.match?("Poky")
|
212
|
+
# assuming the Poky version is preferred over the /etc/version build
|
213
|
+
@platform[:release] = issue[/\d+(\.\d+)+/]
|
214
|
+
true
|
339
215
|
end
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
216
|
+
end
|
217
|
+
|
218
|
+
declare_instance("balenaos", "balenaOS Linux", "yocto") do
|
219
|
+
# balenaOS does have the /etc/os-release file
|
220
|
+
issue = unix_file_contents("/etc/issue")
|
221
|
+
if issue.match?("balenaOS") && linux_os_release["NAME"] =~ /balenaos/i
|
222
|
+
@platform[:release] = linux_os_release["META_BALENA_VERSION"]
|
223
|
+
true
|
348
224
|
end
|
225
|
+
end
|
349
226
|
|
350
227
|
# brocade family detected here if device responds to 'uname' command,
|
351
228
|
# happens when logging in as root
|
352
229
|
plat.family("brocade").title("Brocade Family").in_family("linux")
|
353
230
|
.detect do
|
354
|
-
|
231
|
+
# TODO: no tests
|
232
|
+
brocade_version
|
355
233
|
end
|
356
234
|
|
357
|
-
# generic linux
|
358
235
|
# this should always be last in the linux family list
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
236
|
+
declare_instance("linux", "Generic Linux", "linux") do
|
237
|
+
true
|
238
|
+
end
|
239
|
+
end
|
363
240
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
unless cmd.exit_status != 0 || cmd.stdout.empty?
|
370
|
-
@platform[:name] = cmd.stdout.downcase.split(" ")[0]
|
371
|
-
cmd = @backend.run_command('write sys$output f$getsyi("VERSION")')
|
372
|
-
@platform[:release] = cmd.stdout.downcase.split("\n")[1][1..-1]
|
373
|
-
cmd = @backend.run_command('write sys$output f$getsyi("ARCH_NAME")')
|
374
|
-
@platform[:arch] = cmd.stdout.downcase.split("\n")[1]
|
375
|
-
true
|
376
|
-
end
|
377
|
-
end
|
378
|
-
end
|
241
|
+
def self.load_other_unix
|
242
|
+
declare_instance("openvms", "OpenVMS", "unix") do
|
243
|
+
if unix_uname_s =~ /unrecognized command verb/i
|
244
|
+
# TODO: no tests
|
245
|
+
cmd = @backend.run_command("show system/noprocess")
|
379
246
|
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
m = out.match(/(\d+)\s+(\d+)\s+(.*)/)
|
389
|
-
unless m.nil?
|
390
|
-
@platform[:release] = "#{m[2]}.#{m[1]}"
|
391
|
-
@platform[:arch] = m[3].to_s
|
247
|
+
if cmd.exit_status == 0 && !cmd.stdout.empty?
|
248
|
+
# TODO: no tests
|
249
|
+
@platform[:name] = cmd.stdout.downcase.split(" ")[0]
|
250
|
+
cmd = @backend.run_command('write sys$output f$getsyi("VERSION")')
|
251
|
+
@platform[:release] = cmd.stdout.downcase.split("\n")[1][1..-1]
|
252
|
+
cmd = @backend.run_command('write sys$output f$getsyi("ARCH_NAME")')
|
253
|
+
@platform[:arch] = cmd.stdout.downcase.split("\n")[1]
|
254
|
+
true
|
392
255
|
end
|
393
|
-
true
|
394
256
|
end
|
257
|
+
end
|
395
258
|
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
if unix_uname_s =~ /sunos/i
|
400
|
-
unless (version = /^5\.(?<release>\d+)$/.match(unix_uname_r)).nil?
|
401
|
-
@platform[:release] = version["release"]
|
402
|
-
end
|
259
|
+
declare_category("aix", "unix") do
|
260
|
+
unix_uname_s =~ /aix/i
|
261
|
+
end
|
403
262
|
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
.detect do
|
411
|
-
rel = unix_file_contents("/etc/release")
|
412
|
-
if /^.*(SmartOS).*$/ =~ rel
|
413
|
-
true
|
414
|
-
end
|
415
|
-
end
|
416
|
-
plat.name("omnios").title("Omnios").in_family("solaris")
|
417
|
-
.detect do
|
418
|
-
rel = unix_file_contents("/etc/release")
|
419
|
-
unless (m = /^\s*(OmniOS).*r(\d+).*$/.match(rel)).nil?
|
420
|
-
@platform[:release] = m[2]
|
421
|
-
true
|
422
|
-
end
|
423
|
-
end
|
424
|
-
plat.name("openindiana").title("Openindiana").in_family("solaris")
|
425
|
-
.detect do
|
426
|
-
rel = unix_file_contents("/etc/release")
|
427
|
-
unless (m = /^\s*(OpenIndiana).*oi_(\d+).*$/.match(rel)).nil?
|
428
|
-
@platform[:release] = m[2]
|
429
|
-
true
|
430
|
-
end
|
263
|
+
declare_instance("aix", "Aix", "aix") do
|
264
|
+
out = @backend.run_command("uname -rvp").stdout
|
265
|
+
if out =~ /(\d+)\s+(\d+)\s+(.*)/
|
266
|
+
# TODO: no tests
|
267
|
+
@platform[:release] = "#{$2}.#{$1}"
|
268
|
+
@platform[:arch] = "#{$3}"
|
431
269
|
end
|
432
|
-
|
433
|
-
|
434
|
-
rel = unix_file_contents("/etc/release")
|
435
|
-
unless (m = /^\s*(OpenSolaris).*snv_(\d+).*$/.match(rel)).nil?
|
436
|
-
@platform[:release] = m[2]
|
437
|
-
true
|
438
|
-
end
|
439
|
-
end
|
440
|
-
plat.name("nexentacore").title("Nexentacore").in_family("solaris")
|
441
|
-
.detect do
|
442
|
-
rel = unix_file_contents("/etc/release")
|
443
|
-
if /^\s*(NexentaCore)\s.*$/ =~ rel
|
444
|
-
true
|
445
|
-
end
|
446
|
-
end
|
447
|
-
plat.name("solaris").title("Solaris").in_family("solaris")
|
448
|
-
.detect do
|
449
|
-
rel = unix_file_contents("/etc/release")
|
450
|
-
if !(m = /Oracle Solaris (\d+)/.match(rel)).nil?
|
451
|
-
# TODO: should be string!
|
452
|
-
@platform[:release] = m[1]
|
453
|
-
true
|
454
|
-
elsif /^\s*(Solaris)\s.*$/ =~ rel
|
455
|
-
true
|
456
|
-
end
|
270
|
+
true
|
271
|
+
end
|
457
272
|
|
458
|
-
|
459
|
-
|
460
|
-
|
273
|
+
declare_category("solaris", "unix") do
|
274
|
+
if unix_uname_s =~ /sunos/i
|
275
|
+
# TODO: no tests
|
461
276
|
|
462
|
-
|
463
|
-
plat.family("hpux").in_family("unix")
|
464
|
-
.detect do
|
465
|
-
true if unix_uname_s =~ /hp-ux/i
|
466
|
-
end
|
467
|
-
plat.name("hpux").title("Hpux").in_family("hpux")
|
468
|
-
.detect do
|
469
|
-
@platform[:release] = unix_uname_r.lines[0].chomp
|
470
|
-
true
|
471
|
-
end
|
277
|
+
@platform[:release] = $1 if unix_uname_r =~ /^5\.(\d+)$/
|
472
278
|
|
473
|
-
|
474
|
-
|
475
|
-
.detect do
|
476
|
-
true if unix_uname_s =~ /qnx/i
|
477
|
-
end
|
478
|
-
plat.name("qnx").title("QNX").in_family("qnx")
|
479
|
-
.detect do
|
480
|
-
@platform[:name] = unix_uname_s.lines[0].chomp.downcase
|
481
|
-
@platform[:release] = unix_uname_r.lines[0].chomp
|
482
|
-
@platform[:arch] = unix_uname_m
|
279
|
+
arch = @backend.run_command("uname -p")
|
280
|
+
@platform[:arch] = arch.stdout.chomp if arch.exit_status == 0
|
483
281
|
true
|
484
282
|
end
|
283
|
+
end
|
485
284
|
|
486
|
-
#
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
285
|
+
# TODO: these regexps are probably needlessly wasteful
|
286
|
+
declare_path_regexp("smartos", "SmartOS", "solaris", "/etc/release", /^.*(SmartOS).*$/)
|
287
|
+
|
288
|
+
declare_path("omnios", "Omnios", "solaris", "/etc/release", /^\s*OmniOS.*r(\d+).*$/)
|
289
|
+
declare_path("openindiana", "Openindiana", "solaris", "/etc/release", /^\s*OpenIndiana.*oi_(\d+).*$/)
|
290
|
+
|
291
|
+
declare_path("opensolaris", "Open Solaris", "solaris", "/etc/release", /^\s*OpenSolaris.*snv_(\d+).*$/)
|
292
|
+
|
293
|
+
# TODO: these regexps are probably needlessly wasteful
|
294
|
+
declare_path_regexp("nexentacore", "Nexentacore", "solaris", "/etc/release", /^\s*(NexentaCore)\s.*$/)
|
295
|
+
|
296
|
+
declare_instance("solaris", "Solaris", "solaris") do
|
297
|
+
rel = unix_file_contents("/etc/release")
|
298
|
+
if rel =~ /Oracle Solaris (\d+)/
|
299
|
+
@platform[:release] = $1
|
300
|
+
# TODO: no tests
|
491
301
|
true
|
492
|
-
|
493
|
-
|
494
|
-
.detect do
|
495
|
-
if unix_uname_s =~ /darwin/i
|
496
|
-
cmd = unix_file_contents("/usr/bin/sw_vers")
|
497
|
-
unless cmd.nil?
|
498
|
-
m = cmd.match(/^ProductVersion:\s+(.+)$/)
|
499
|
-
@platform[:release] = m.nil? ? nil : m[1]
|
500
|
-
m = cmd.match(/^BuildVersion:\s+(.+)$/)
|
501
|
-
@platform[:build] = m.nil? ? nil : m[1]
|
502
|
-
end
|
503
|
-
@platform[:release] = unix_uname_r.lines[0].chomp if @platform[:release].nil?
|
504
|
-
@platform[:arch] = unix_uname_m
|
505
|
-
true
|
506
|
-
end
|
507
|
-
end
|
508
|
-
plat.name("mac_os_x").title("macOS X").in_family("darwin")
|
509
|
-
.detect do
|
510
|
-
cmd = unix_file_contents("/System/Library/CoreServices/SystemVersion.plist")
|
511
|
-
@platform[:uuid_command] = "system_profiler SPHardwareDataType | awk '/UUID/ { print $3; }'"
|
512
|
-
true if cmd =~ /Mac OS X/i
|
513
|
-
end
|
514
|
-
plat.name("darwin").title("Darwin").in_family("darwin")
|
515
|
-
.detect do
|
516
|
-
# must be some other type of darwin
|
517
|
-
@platform[:name] = unix_uname_s.lines[0].chomp
|
302
|
+
elsif rel =~ /^\s*(Solaris)\s.*$/
|
303
|
+
# TODO: no tests
|
518
304
|
true
|
519
305
|
end
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
306
|
+
|
307
|
+
# TODO: no tests
|
308
|
+
|
309
|
+
# must be some unknown solaris
|
310
|
+
true
|
311
|
+
end
|
312
|
+
|
313
|
+
declare_category("hpux", "unix") do
|
314
|
+
unix_uname_s =~ /hp-ux/i
|
315
|
+
end
|
316
|
+
|
317
|
+
declare_instance("hpux", "Hpux", "hpux") do
|
318
|
+
@platform[:release] = unix_uname_r.lines[0].chomp
|
319
|
+
# TODO: no tests
|
320
|
+
true
|
321
|
+
end
|
322
|
+
|
323
|
+
declare_category("qnx", "unix") do
|
324
|
+
unix_uname_s =~ /qnx/i
|
325
|
+
end
|
326
|
+
|
327
|
+
declare_instance("qnx", "QNX", "qnx") do
|
328
|
+
# TODO: refactor these uname patterns
|
329
|
+
@platform[:name] = unix_uname_s.lines[0].chomp.downcase
|
330
|
+
@platform[:release] = unix_uname_r.lines[0].chomp
|
331
|
+
@platform[:arch] = unix_uname_m
|
332
|
+
true
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
def self.load_bsd
|
337
|
+
declare_category("bsd", "unix") do
|
338
|
+
# we need a better way to determine this family
|
339
|
+
# for now we are going to just try each platform
|
340
|
+
true
|
341
|
+
end
|
342
|
+
|
343
|
+
declare_category("darwin", "bsd") do
|
344
|
+
# rubocop:disable Layout/ExtraSpacing
|
345
|
+
# rubocop:disable Layout/SpaceAroundOperators
|
346
|
+
if unix_uname_s =~ /darwin/i
|
347
|
+
@platform[:release] ||= unix_uname_r.lines[0].chomp
|
348
|
+
@platform[:arch] = unix_uname_m
|
349
|
+
cmd = @backend.run_command("sw_vers -buildVersion")
|
350
|
+
@platform[:build] = cmd.stdout.chomp if cmd.exit_status == 0
|
351
|
+
true
|
543
352
|
end
|
353
|
+
# rubocop:enable Layout/ExtraSpacing
|
354
|
+
# rubocop:enable Layout/SpaceAroundOperators
|
355
|
+
end
|
356
|
+
|
357
|
+
declare_instance("mac_os_x", "macOS X", "darwin") do
|
358
|
+
cmd = unix_file_contents("/System/Library/CoreServices/SystemVersion.plist")
|
359
|
+
@platform[:uuid_command] = "system_profiler SPHardwareDataType | awk '/UUID/ { print $3; }'"
|
360
|
+
cmd =~ /Mac OS X/i
|
361
|
+
end
|
362
|
+
|
363
|
+
declare_instance("darwin", "Darwin", "darwin") do
|
364
|
+
# must be some other type of darwin
|
365
|
+
@platform[:name] = unix_uname_s.lines[0].chomp
|
366
|
+
true
|
367
|
+
end
|
368
|
+
|
369
|
+
declare_bsd("freebsd", "Freebsd", "bsd", /freebsd/i)
|
370
|
+
declare_bsd("openbsd", "Openbsd", "bsd", /openbsd/i)
|
371
|
+
declare_bsd("netbsd", "Netbsd", "bsd", /netbsd/i)
|
372
|
+
end
|
544
373
|
|
545
|
-
|
374
|
+
def self.load_other
|
546
375
|
plat.family("arista_eos").title("Arista EOS Family").in_family("os")
|
547
376
|
.detect do
|
548
377
|
true
|
549
378
|
end
|
550
|
-
plat.name("arista_eos").title("Arista EOS").in_family("arista_eos")
|
551
|
-
.detect do
|
552
|
-
cmd = @backend.run_command("show version | json")
|
553
|
-
if cmd.exit_status == 0 && !cmd.stdout.empty?
|
554
|
-
require "json"
|
555
|
-
begin
|
556
|
-
eos_ver = JSON.parse(cmd.stdout)
|
557
|
-
@platform[:release] = eos_ver["version"]
|
558
|
-
@platform[:arch] = eos_ver["architecture"]
|
559
|
-
true
|
560
|
-
rescue JSON::ParserError
|
561
|
-
nil
|
562
|
-
end
|
563
|
-
end
|
564
|
-
end
|
565
379
|
|
566
|
-
|
380
|
+
declare_instance("arista_eos", "Arista EOS", "arista_eos") do
|
381
|
+
json_cmd("show version | json")
|
382
|
+
end
|
383
|
+
|
567
384
|
plat.family("esx").title("ESXi Family").in_family("os")
|
568
385
|
.detect do
|
569
|
-
|
386
|
+
unix_uname_s =~ /vmkernel/i
|
570
387
|
end
|
388
|
+
|
571
389
|
plat.name("vmkernel").in_family("esx")
|
572
390
|
.detect do
|
573
|
-
|
574
|
-
|
575
|
-
true
|
391
|
+
# TODO: no tests
|
392
|
+
set_from_uname
|
576
393
|
end
|
577
394
|
|
578
|
-
# cisco_ios family
|
579
395
|
plat.family("cisco").title("Cisco Family").in_family("os")
|
580
396
|
.detect do
|
581
|
-
|
397
|
+
cisco_show_version
|
582
398
|
end
|
583
|
-
plat.name("cisco_ios").title("Cisco IOS").in_family("cisco")
|
584
|
-
.detect do
|
585
|
-
v = cisco_show_version
|
586
|
-
next unless v[:type] == "ios"
|
587
399
|
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
plat.
|
400
|
+
declare_cisco("cisco_ios", "Cisco IOS", "cisco", :cisco_show_version, "ios")
|
401
|
+
declare_cisco("cisco_ios_xe", "Cisco IOS XE", "cisco", :cisco_show_version, "ios-xe")
|
402
|
+
declare_cisco("cisco_nexus", "Cisco Nexus", "cisco", :cisco_show_version, "nexus", "show version | include Processor")
|
403
|
+
|
404
|
+
plat.family("brocade").title("Brocade Family").in_family("os")
|
593
405
|
.detect do
|
594
|
-
|
595
|
-
|
406
|
+
brocade_version
|
407
|
+
end
|
408
|
+
|
409
|
+
declare_cisco("brocade_fos", "Brocade FOS", "brocade", :brocade_version, "fos")
|
410
|
+
end
|
411
|
+
|
412
|
+
######################################################################
|
413
|
+
# Helpers (keep these sorted)
|
414
|
+
|
415
|
+
def self.plat
|
416
|
+
Train::Platforms
|
417
|
+
end
|
418
|
+
|
419
|
+
def self.declare_category(family, parent, &block)
|
420
|
+
plat.family(family).in_family(parent).detect(&block)
|
421
|
+
end
|
422
|
+
|
423
|
+
def self.declare_family(name, title = nil, family, &block)
|
424
|
+
thingy = plat.name(name).in_family(family)
|
425
|
+
thingy.title(title) if title
|
426
|
+
thingy.detect(&block)
|
427
|
+
end
|
428
|
+
|
429
|
+
def self.declare_instance(name, title, family, &block)
|
430
|
+
plat.name(name).title(title).in_family(family).detect(&block)
|
431
|
+
end
|
432
|
+
|
433
|
+
def self.declare_bsd(name, title, family, regexp)
|
434
|
+
declare_instance(name, title, family) do
|
435
|
+
# TODO: no tests
|
436
|
+
set_from_uname if unix_uname_s =~ regexp
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
def self.declare_cisco(name, title, family, detect, type, uuid = nil)
|
441
|
+
declare_instance(name, title, family) do
|
442
|
+
v = send(detect)
|
443
|
+
|
444
|
+
next unless v[:type] == type
|
596
445
|
|
597
|
-
|
598
|
-
|
446
|
+
@platform[:release] = v[:version]
|
447
|
+
@platform[:arch] = nil
|
448
|
+
@platform[:uuid_command] = uuid if uuid
|
449
|
+
true
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
def self.declare_file_content(name, title, family, path)
|
454
|
+
declare_instance(name, title, family) do
|
455
|
+
if (raw = unix_file_contents(path))
|
456
|
+
# TODO: no tests
|
457
|
+
@platform[:release] = raw.scan(/[\d.]+/).join
|
599
458
|
true
|
600
459
|
end
|
601
|
-
|
602
|
-
|
603
|
-
v = cisco_show_version
|
604
|
-
next unless v[:type] == "nexus"
|
460
|
+
end
|
461
|
+
end
|
605
462
|
|
606
|
-
|
607
|
-
|
608
|
-
|
463
|
+
def self.declare_lsb(name, title, family, regexp)
|
464
|
+
declare_lsb_or_content(name, title, family, nil, regexp)
|
465
|
+
end
|
466
|
+
|
467
|
+
def self.declare_lsb_or_content(name, title, family, path, regexp1, regexp2 = regexp1)
|
468
|
+
declare_instance(name, title, family) do
|
469
|
+
lsb = read_linux_lsb
|
470
|
+
if lsb && lsb[:id] =~ regexp1
|
471
|
+
@platform[:release] = lsb[:release]
|
472
|
+
true
|
473
|
+
elsif path && (raw = unix_file_contents(path)) =~ regexp2
|
474
|
+
@platform[:name] = redhatish_platform(raw)
|
475
|
+
@platform[:release] = redhatish_version(raw)
|
609
476
|
true
|
610
477
|
end
|
478
|
+
end
|
479
|
+
end
|
611
480
|
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
481
|
+
def self.declare_os_or_file(name, title, family, path, regexp1, regexp2 = regexp1)
|
482
|
+
declare_instance(name, title, family) do
|
483
|
+
rel = linux_os_release
|
484
|
+
(rel && rel["NAME"] =~ regexp1) ||
|
485
|
+
unix_file_contents(path) =~ regexp2
|
486
|
+
end
|
487
|
+
end
|
617
488
|
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
489
|
+
def self.declare_path(name, title, family, path, regexp)
|
490
|
+
declare_instance(name, title, family) do
|
491
|
+
rel = unix_file_contents(path)
|
492
|
+
if rel =~ regexp
|
493
|
+
# TODO: no tests
|
494
|
+
@platform[:release] = $1
|
495
|
+
true
|
496
|
+
end
|
497
|
+
end
|
498
|
+
end
|
622
499
|
|
623
|
-
|
624
|
-
|
500
|
+
def self.declare_path_and_uname(name, title, family, path)
|
501
|
+
declare_instance(name, title, family) do
|
502
|
+
if unix_file_exist?(path)
|
503
|
+
# Because this is a rolling release distribution,
|
504
|
+
# use the kernel release, ex. 4.1.6-1-ARCH
|
505
|
+
# TODO: unix_uname_r.lines[0].chomp ? -- no tests for /etc/exherbo-release or /etc/arch-release
|
506
|
+
@platform[:release] = unix_uname_r
|
625
507
|
true
|
626
508
|
end
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
def self.declare_path_regexp(name, title, family, path, regexp)
|
513
|
+
declare_instance(name, title, family) do
|
514
|
+
# TODO: no tests
|
515
|
+
regexp =~ unix_file_contents(path)
|
516
|
+
end
|
627
517
|
end
|
628
518
|
end
|
629
519
|
end
|