ohai 14.5.4 → 14.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ohai/application.rb +19 -0
  3. data/lib/ohai/exception.rb +1 -0
  4. data/lib/ohai/hints.rb +5 -0
  5. data/lib/ohai/log.rb +2 -0
  6. data/lib/ohai/plugins/cpu.rb +416 -0
  7. data/lib/ohai/plugins/darwin/hardware.rb +1 -7
  8. data/lib/ohai/plugins/darwin/system_profiler.rb +19 -19
  9. data/lib/ohai/plugins/filesystem.rb +326 -115
  10. data/lib/ohai/plugins/linux/platform.rb +1 -1
  11. data/lib/ohai/plugins/os.rb +16 -0
  12. data/lib/ohai/system.rb +12 -2
  13. data/lib/ohai/version.rb +1 -1
  14. data/spec/unit/plugins/aix/cpu_spec.rb +1 -1
  15. data/spec/unit/plugins/aix/filesystem_spec.rb +23 -1
  16. data/spec/unit/plugins/darwin/cpu_spec.rb +3 -3
  17. data/spec/unit/plugins/freebsd/cpu_spec.rb +2 -2
  18. data/spec/unit/plugins/linux/cpu_spec.rb +3 -3
  19. data/spec/unit/plugins/linux/platform_spec.rb +2 -1
  20. data/spec/unit/plugins/os_spec.rb +33 -0
  21. data/spec/unit/plugins/solaris2/cpu_spec.rb +1 -1
  22. data/spec/unit/plugins/solaris2/filesystem.rb +355 -32
  23. data/spec/unit/plugins/windows/cpu_spec.rb +1 -1
  24. metadata +3 -18
  25. data/lib/ohai/plugins/aix/cpu.rb +0 -64
  26. data/lib/ohai/plugins/aix/filesystem.rb +0 -90
  27. data/lib/ohai/plugins/aix/os.rb +0 -30
  28. data/lib/ohai/plugins/darwin/cpu.rb +0 -50
  29. data/lib/ohai/plugins/dragonflybsd/cpu.rb +0 -58
  30. data/lib/ohai/plugins/dragonflybsd/os.rb +0 -31
  31. data/lib/ohai/plugins/freebsd/cpu.rb +0 -70
  32. data/lib/ohai/plugins/freebsd/os.rb +0 -32
  33. data/lib/ohai/plugins/linux/cpu.rb +0 -120
  34. data/lib/ohai/plugins/netbsd/cpu.rb +0 -50
  35. data/lib/ohai/plugins/openbsd/cpu.rb +0 -43
  36. data/lib/ohai/plugins/solaris2/cpu.rb +0 -70
  37. data/lib/ohai/plugins/solaris2/filesystem.rb +0 -106
  38. data/lib/ohai/plugins/windows/cpu.rb +0 -59
  39. data/spec/unit/plugins/aix/os_spec.rb +0 -35
  40. data/spec/unit/plugins/freebsd/os_spec.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 43d635401a670d3a17696baedc004962bbabb702055df16763a8814f920fa3ce
4
- data.tar.gz: 75d091cb7e4d9e8993224ed95b2dd19212293afb925e7b202325cacac2157105
3
+ metadata.gz: 71c27302cdf32368fc8014db58963f0e743021c347761701b714e6221013b417
4
+ data.tar.gz: 9e904244a04b14fb93f604de5a911efc087dd9c6a037e5b995363b9ade746e32
5
5
  SHA512:
6
- metadata.gz: 532516c9be86772a63d5cdd33b6f6533e99a4861cead69cf67c5f3fa4695635731de6511e009b08f2930390908a3ed63ab249c5f42c3d7ff5b457a73537301b1
7
- data.tar.gz: 05c0a5ea12747b483379734911f40c18cd17fb7cc22ef1484bf6d8ff97f90127631d543e5051bd9debbc4970696ee44a47ea486a226c8dea4a6457c8d10405c2
6
+ metadata.gz: 3639681908ec02d8c06900c886ad41a91303084920e476ce5c83d11b62fe27040ccd5dcd33af444f481bd6738a8e47ad01c6613235d339b46dd0a638ccabb8b5
7
+ data.tar.gz: 6cdc5bc33fea99cade6973bb778a3101f6b4bb2eccee9db83b37a4b1bcfe2fb88e86189377500cb0aae280305891becca4dbf589cf2519b52d99194cf07ba064
@@ -22,6 +22,10 @@ require "ohai/log"
22
22
  require "mixlib/cli"
23
23
  require "benchmark"
24
24
 
25
+ # The Application class is what is called by the Ohai CLI binary. It handles:
26
+ # - CLI options and attribute arguments
27
+ # - Collecting data via the Ohai::System class
28
+ # - Printing the results returned via the Ohai::System class
25
29
  class Ohai::Application
26
30
  include Mixlib::CLI
27
31
 
@@ -69,6 +73,9 @@ class Ohai::Application
69
73
  proc: lambda { |v| puts "Ohai: #{::Ohai::VERSION}" },
70
74
  exit: 0
71
75
 
76
+ # the method called by the Ohai binary to actually run the whole application
77
+ #
78
+ # @return void
72
79
  def run
73
80
  elapsed = Benchmark.measure do
74
81
  configure_ohai
@@ -77,6 +84,9 @@ class Ohai::Application
77
84
  Ohai::Log.debug("Ohai took #{elapsed.total} total seconds to run.")
78
85
  end
79
86
 
87
+ # parses the CLI options, loads the config file if present, and initializes logging
88
+ #
89
+ # @return void
80
90
  def configure_ohai
81
91
  @attributes = parse_options
82
92
  @attributes = nil if @attributes.empty?
@@ -86,6 +96,10 @@ class Ohai::Application
86
96
  Ohai::Log.init(Ohai.config[:log_location])
87
97
  end
88
98
 
99
+ # Passes config and attributes arguments to Ohai::System then prints the results.
100
+ # Called by the run method after config / logging have been initialized
101
+ #
102
+ # @return void
89
103
  def run_application
90
104
  # Always switch to a readable directory. Keeps subsequent Dir.chdir() {}
91
105
  # from failing due to permissions when launched as a less privileged user.
@@ -107,12 +121,17 @@ class Ohai::Application
107
121
 
108
122
  class << self
109
123
  # Log a fatal error message to both STDERR and the Logger, exit the application
124
+ # @param msg [String] the message to log
125
+ # @param err [Integer] the exit code
110
126
  def fatal!(msg, err = -1)
111
127
  STDERR.puts("FATAL: #{msg}")
112
128
  Ohai::Log.fatal(msg)
113
129
  Process.exit err
114
130
  end
115
131
 
132
+ # Log a debug message to the Logger and then exit the application
133
+ # @param msg [String] the message to log
134
+ # @param err [Integer] the exit code
116
135
  def exit!(msg, err = -1)
117
136
  Ohai::Log.debug(msg)
118
137
  Process.exit err
@@ -17,6 +17,7 @@
17
17
  #
18
18
 
19
19
  module Ohai
20
+ # Ohai specific exceptions
20
21
  module Exceptions
21
22
  class Exec < RuntimeError; end
22
23
  class Error < StandardError; end
@@ -20,6 +20,11 @@
20
20
  require "ffi_yajl"
21
21
 
22
22
  module Ohai
23
+ # Ohai hints are json files on disk that give ohai a hint to things that are often
24
+ # difficult to discover like certain clouds. Previously they were used for just about
25
+ # every cloud, but we've since discoverd better ways to auto-detect these clouds.
26
+ # They are generally dropped off by the knife plugins for those clouds during bootstrap,
27
+ # but may also be manually dropped off and consumed by 3rd party plugins.
23
28
  module Hints
24
29
  # clear out any known hints in the @hints variable
25
30
  def self.refresh_hints
@@ -19,6 +19,8 @@
19
19
  require "mixlib/log"
20
20
 
21
21
  module Ohai
22
+ # the Ohai Logger which is just Mixlib::Log defaulting to STDERR and :info level
23
+ # unless otherwise configured via CLI or config
22
24
  class Log
23
25
  extend Mixlib::Log
24
26
 
@@ -0,0 +1,416 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@chef.io>)
3
+ # Author:: Bryan McLellan (btm@loftninjas.org)
4
+ # Author:: Tim Smith (tsmith@chef.io)
5
+ # Author:: Mathieu Sauve-Frankel <msf@kisoku.net>
6
+ # Author:: Nathan L Smith (<nlloyds@gmail.com>)
7
+ # Author:: Joshua Timberman <joshua@chef.io>
8
+ # Author:: Prabhu Das (<prabhu.das@clogeny.com>)
9
+ # Author:: Isa Farnik (<isa@chef.io>)
10
+ # Author:: Doug MacEachern <dougm@vmware.com>
11
+ # Copyright:: Copyright (c) 2008-2018 Chef Software, Inc.
12
+ # License:: Apache License, Version 2.0
13
+ #
14
+ # Licensed under the Apache License, Version 2.0 (the "License");
15
+ # you may not use this file except in compliance with the License.
16
+ # You may obtain a copy of the License at
17
+ #
18
+ # http://www.apache.org/licenses/LICENSE-2.0
19
+ #
20
+ # Unless required by applicable law or agreed to in writing, software
21
+ # distributed under the License is distributed on an "AS IS" BASIS,
22
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
+ # See the License for the specific language governing permissions and
24
+ # limitations under the License.
25
+ #
26
+
27
+ Ohai.plugin(:CPU) do
28
+ provides "cpu"
29
+
30
+ def parse_bsd_dmesg(&block)
31
+ cpuinfo = Mash.new
32
+ cpuinfo["flags"] = []
33
+ File.open("/var/run/dmesg.boot").each do |line|
34
+ case line
35
+ when /CPU:\s+(.+) \(([\d.]+).+\)/
36
+ cpuinfo["model_name"] = $1
37
+ cpuinfo["mhz"] = $2
38
+ when /Features=.+<(.+)>/
39
+ cpuinfo["flags"].concat($1.downcase.split(","))
40
+ # Features2=0x80000001<SSE3,<b31>>
41
+ when /Features2=[a-f\dx]+<(.+)>/
42
+ cpuinfo["flags"].concat($1.downcase.split(","))
43
+ else
44
+ yield(cpuinfo, line)
45
+ end
46
+ end
47
+ cpuinfo
48
+ end
49
+
50
+ collect_data(:linux) do
51
+ cpuinfo = Mash.new
52
+ real_cpu = Mash.new
53
+ cpu_number = 0
54
+ current_cpu = nil
55
+
56
+ File.open("/proc/cpuinfo").each do |line|
57
+ case line
58
+ when /processor\s+:\s(.+)/
59
+ cpuinfo[$1] = Mash.new
60
+ current_cpu = $1
61
+ cpu_number += 1
62
+ when /vendor_id\s+:\s(.+)/
63
+ vendor_id = $1
64
+ if vendor_id =~ (/IBM\/S390/)
65
+ cpuinfo["vendor_id"] = vendor_id
66
+ else
67
+ cpuinfo[current_cpu]["vendor_id"] = vendor_id
68
+ end
69
+ when /cpu family\s+:\s(.+)/
70
+ cpuinfo[current_cpu]["family"] = $1
71
+ when /model\s+:\s(.+)/
72
+ cpuinfo[current_cpu]["model"] = $1
73
+ when /stepping\s+:\s(.+)/
74
+ cpuinfo[current_cpu]["stepping"] = $1
75
+ when /physical id\s+:\s(.+)/
76
+ cpuinfo[current_cpu]["physical_id"] = $1
77
+ real_cpu[$1] = true
78
+ when /core id\s+:\s(.+)/
79
+ cpuinfo[current_cpu]["core_id"] = $1
80
+ when /cpu cores\s+:\s(.+)/
81
+ cpuinfo[current_cpu]["cores"] = $1
82
+ when /model name\s+:\s(.+)/
83
+ cpuinfo[current_cpu]["model_name"] = $1
84
+ when /cpu MHz\s+:\s(.+)/
85
+ cpuinfo[current_cpu]["mhz"] = $1
86
+ when /cache size\s+:\s(.+)/
87
+ cpuinfo[current_cpu]["cache_size"] = $1
88
+ when /flags\s+:\s(.+)/
89
+ cpuinfo[current_cpu]["flags"] = $1.split(" ")
90
+ when /BogoMIPS\s+:\s(.+)/
91
+ cpuinfo[current_cpu]["bogomips"] = $1
92
+ when /Features\s+:\s(.+)/
93
+ cpuinfo[current_cpu]["features"] = $1.split(" ")
94
+ when /bogomips per cpu:\s(.+)/
95
+ cpuinfo["bogomips_per_cpu"] = $1
96
+ when /features\s+:\s(.+)/
97
+ cpuinfo["features"] = $1.split(" ")
98
+ when /processor\s(\d):\s(.+)/
99
+ current_cpu = $1
100
+ cpu_number += 1
101
+ cpuinfo[current_cpu] = Mash.new
102
+ current_cpu_info = $2.split(",")
103
+ current_cpu_info.each do |i|
104
+ name_value = i.split("=")
105
+ name = name_value[0].strip
106
+ value = name_value[1].strip
107
+ cpuinfo[current_cpu][name] = value
108
+ end
109
+ end
110
+ end
111
+
112
+ cpu cpuinfo
113
+
114
+ cpu[:total] = cpu_number
115
+
116
+ # use data we collected unless cpuinfo is lacking core information
117
+ # which is the case on older linux distros
118
+ if !real_cpu.empty? && cpu["0"]["cores"]
119
+ cpu[:real] = real_cpu.keys.length
120
+ cpu[:cores] = real_cpu.keys.length * cpu["0"]["cores"].to_i
121
+ else
122
+ begin
123
+ logger.trace("Plugin CPU: Falling back to aggregate data from lscpu as real cpu & core data is missing in /proc/cpuinfo")
124
+ so = shell_out("lscpu")
125
+ if so.exitstatus == 0
126
+ lscpu_data = Mash.new
127
+ so.stdout.each_line do |line|
128
+ case line
129
+ when /^Thread\(s\) per core:\s(.+)/ # http://rubular.com/r/lOw2pRrw1q
130
+ lscpu_data[:threads] = $1.to_i
131
+ when /^Core\(s\) per socket:\s(.+)/ # http://rubular.com/r/lOw2pRrw1q
132
+ lscpu_data[:cores] = $1.to_i
133
+ when /^Socket\(s\):\s(.+)/ # http://rubular.com/r/DIzmPtJFvK
134
+ lscpu_data[:sockets] = $1.to_i
135
+ end
136
+ end
137
+ cpu[:total] = lscpu_data[:sockets] * lscpu_data[:cores] * lscpu_data[:threads]
138
+ cpu[:real] = lscpu_data[:sockets]
139
+ cpu[:cores] = lscpu_data[:sockets] * lscpu_data[:cores]
140
+ else
141
+ logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
142
+ end
143
+ rescue Ohai::Exceptions::Exec # util-linux isn't installed most likely
144
+ logger.trace("Plugin CPU: Error executing lscpu. util-linux may not be installed.")
145
+ end
146
+ end
147
+ end
148
+
149
+ collect_data(:freebsd) do
150
+ # all dmesg output for smp I can find only provides info about a single processor
151
+ # identical processors is probably a hardware requirement so we'll duplicate data for each cpu
152
+ # old examples: http://www.bnv-bamberg.de/home/ba3294/smp/rbuild/index.htm
153
+
154
+ # /var/run/dmesg.boot
155
+ # CPU: Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz (2793.59-MHz K8-class CPU)
156
+ # Origin="GenuineIntel" Id=0x40661 Family=0x6 Model=0x46 Stepping=1
157
+ # Features=0x783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2>
158
+ # Features2=0x5ed8220b<SSE3,PCLMULQDQ,MON,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,AVX,RDRAND>
159
+ # AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
160
+ # AMD Features2=0x21<LAHF,ABM>
161
+ # Structured Extended Features=0x2000<NFPUSG>
162
+ # TSC: P-state invariant
163
+ # ...
164
+ # FreeBSD/SMP: Multiprocessor System Detected: 16 CPUs
165
+ # FreeBSD/SMP: 2 package(s) x 4 core(s) x 2 SMT threads
166
+
167
+ info = parse_bsd_dmesg do |cpuinfo, line|
168
+ case line
169
+ when /Origin.*"(.*)".*Family.*0x(\S+).*Model.*0x(\S+).*Stepping.*(\S+)/
170
+ cpuinfo["vendor_id"] = $1
171
+ # convert from hex value to int, but keep a string to match Linux ohai
172
+ cpuinfo["family"] = $2.to_i(16).to_s
173
+ cpuinfo["model"] = $3.to_i(16).to_s
174
+ cpuinfo["stepping"] = $4
175
+ # These _should_ match /AMD Features2?/ lines as well
176
+ when /FreeBSD\/SMP: Multiprocessor System Detected: (\d*) CPUs/
177
+ cpuinfo["total"] = $1.to_i
178
+ when /FreeBSD\/SMP: (\d*) package\(s\) x (\d*) core\(s\)/
179
+ cpuinfo["real"] = $1.to_i
180
+ cpuinfo["cores"] = $1.to_i * $2.to_i
181
+ end
182
+ end
183
+ cpu info
184
+ end
185
+
186
+ collect_data(:dragonflybsd) do
187
+ # /var/run/dmesg.boot
188
+ # CPU: Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz (3516.61-MHz K8-class CPU)
189
+ # Origin = "GenuineIntel" Id = 0x306a9 Family = 6 Model = 3a Stepping = 9
190
+ # Features=0x783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2>
191
+ # Features2=0x209<SSE3,MON,SSSE3>
192
+ # AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
193
+ # AMD Features2=0x1<LAHF>
194
+
195
+ info = parse_bsd_dmesg do |cpuinfo, line|
196
+ case line
197
+ when /Origin = "(.+)"\s+Id = (.+)\s+Stepping = (.+)/
198
+ cpuinfo["vendor_id"] = $1
199
+ cpuinfo["stepping"] = $3
200
+ end
201
+ end
202
+
203
+ so = shell_out("sysctl -n hw.ncpu")
204
+ info[:total] = so.stdout.split($/)[0].to_i
205
+ cpu info
206
+ end
207
+
208
+ collect_data(:openbsd) do
209
+ cpuinfo = Mash.new
210
+
211
+ # OpenBSD provides most cpu information via sysctl, the only thing we need to
212
+ # to scrape from dmesg.boot is the cpu feature list.
213
+ # cpu0: FPU,V86,DE,PSE,TSC,MSR,MCE,CX8,SEP,MTRR,PGE,MCA,CMOV,PAT,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,TM,SBF,EST,TM2
214
+
215
+ File.open("/var/run/dmesg.boot").each do |line|
216
+ case line
217
+ when /cpu\d+:\s+([A-Z]+$|[A-Z]+,.*$)/
218
+ cpuinfo["flags"] = $1.downcase.split(",")
219
+ end
220
+ end
221
+
222
+ [["hw.model", :model_name], ["hw.ncpu", :total], ["hw.cpuspeed", :mhz]].each do |param, node|
223
+ so = shell_out("sysctl -n #{param}")
224
+ cpuinfo[node] = so.stdout.split($/)[0]
225
+ end
226
+
227
+ cpu cpuinfo
228
+ end
229
+
230
+ collect_data(:netbsd) do
231
+ cpuinfo = Mash.new
232
+
233
+ # NetBSD provides some cpu information via sysctl, and a little via dmesg.boot
234
+ # unlike OpenBSD and FreeBSD, NetBSD does not provide information about the
235
+ # available instruction set
236
+ # cpu0 at mainbus0 apid 0: Intel 686-class, 2134MHz, id 0x6f6
237
+
238
+ File.open("/var/run/dmesg.boot").each do |line|
239
+ case line
240
+ when /cpu[\d\w\s]+:\s([\w\s\-]+),\s+(\w+),/
241
+ cpuinfo[:model_name] = $1
242
+ cpuinfo[:mhz] = $2.gsub(/mhz/i, "")
243
+ end
244
+ end
245
+
246
+ flags = []
247
+ so = shell_out("dmidecode")
248
+ so.stdout.lines do |line|
249
+ if line =~ /^\s+([A-Z\d-]+)\s+\([\w\s-]+\)$/
250
+ flags << $1.downcase
251
+ end
252
+ end
253
+
254
+ cpuinfo[:flags] = flags unless flags.empty?
255
+
256
+ cpu cpuinfo
257
+ end
258
+
259
+ collect_data(:darwin) do
260
+ cpu Mash.new
261
+ shell_out("sysctl hw machdep").stdout.lines.each do |line|
262
+ case line
263
+ when /^hw.packages: (.*)$/
264
+ cpu[:real] = Regexp.last_match[1].to_i
265
+ when /^hw.physicalcpu: (.*)$/
266
+ cpu[:cores] = Regexp.last_match[1].to_i
267
+ when /^hw.logicalcpu: (.*)$/
268
+ cpu[:total] = Regexp.last_match[1].to_i
269
+ when /^hw.cpufrequency: (.*)$/
270
+ cpu[:mhz] = Regexp.last_match[1].to_i / 1000000
271
+ when /^machdep.cpu.vendor: (.*)$/
272
+ cpu[:vendor_id] = Regexp.last_match[1].chomp
273
+ when /^machdep.cpu.brand_string: (.*)$/
274
+ cpu[:model_name] = Regexp.last_match[1].chomp
275
+ when /^machdep.cpu.model: (.*)$/
276
+ cpu[:model] = Regexp.last_match[1].to_i
277
+ when /^machdep.cpu.family: (.*)$/
278
+ cpu[:family] = Regexp.last_match[1].to_i
279
+ when /^machdep.cpu.stepping: (.*)$/
280
+ cpu[:stepping] = Regexp.last_match[1].to_i
281
+ when /^machdep.cpu.features: (.*)$/
282
+ cpu[:flags] = Regexp.last_match[1].downcase.split(" ")
283
+ end
284
+ end
285
+ end
286
+
287
+ collect_data(:aix) do
288
+ cpu Mash.new
289
+
290
+ cpu[:total] = shell_out("pmcycles -m").stdout.lines.length
291
+
292
+ # The below is only relevent on an LPAR
293
+ if shell_out("uname -W").stdout.strip == "0"
294
+
295
+ # At least one CPU will be available, but we'll wait to increment this later.
296
+ cpu[:available] = 0
297
+
298
+ cpudevs = shell_out("lsdev -Cc processor").stdout.lines
299
+ # from http://www-01.ibm.com/software/passportadvantage/pvu_terminology_for_customers.html
300
+ # on AIX number of cores and processors are considered same
301
+ cpu[:real] = cpu[:cores] = cpudevs.length
302
+ cpudevs.each.with_index do |c, i|
303
+ name, status, location = c.split
304
+ index = i.to_s
305
+ cpu[index] = Mash.new
306
+ cpu[index][:status] = status
307
+ cpu[index][:location] = location
308
+ if status =~ /Available/
309
+ cpu[:available] += 1
310
+ lsattr = shell_out("lsattr -El #{name}").stdout.lines
311
+ lsattr.each do |attribute|
312
+ attrib, value = attribute.split
313
+ if attrib == "type"
314
+ cpu[index][:model_name] = value
315
+ elsif attrib == "frequency"
316
+ cpu[index][:mhz] = value.to_i / (1000 * 1000) # convert from hz to MHz
317
+ else
318
+ cpu[index][attrib] = value
319
+ end
320
+ end
321
+ # IBM is the only maker of CPUs for AIX systems.
322
+ cpu[index][:vendor_id] = "IBM"
323
+ end
324
+ end
325
+ end
326
+ end
327
+
328
+ collect_data(:solaris2) do
329
+ cpu Mash.new
330
+ # This does assume that /usr/bin/kstat is in the path
331
+ processor_info = shell_out("kstat -p cpu_info").stdout.lines
332
+ cpu["total"] = 0
333
+ cpu["sockets"] = 0
334
+ cpu["cores"] = 0
335
+ cpu["corethreads"] = 0
336
+ cpu["cpustates"] = Mash.new
337
+
338
+ currentcpu = 0
339
+ cpucores = Array.new
340
+ cpusockets = Array.new
341
+ processor_info.each do |processor|
342
+ _desc, instance, _record, keyvalue = processor.split(":")
343
+ cpu[instance] ||= Mash.new
344
+ if currentcpu != instance
345
+ cpu["total"] += 1
346
+ currentcpu = instance
347
+ end
348
+ kv = keyvalue.split(/\s+/)
349
+ key = kv.shift
350
+ value = kv.join(" ").chomp
351
+ case key
352
+ when /chip_id/
353
+ cpu[instance]["socket"] = value
354
+ cpusockets.push(value) if cpusockets.index(value).nil?
355
+ when /cpu_type/
356
+ cpu[instance]["arch"] = value
357
+ when /clock_MHz/
358
+ cpu[instance]["mhz"] = value
359
+ when /brand/
360
+ cpu[instance]["model_name"] = value.sub(/\s+/, " ")
361
+ when /^state$/
362
+ cpu[instance]["state"] = value
363
+ cpu["cpustates"][value] ||= 0
364
+ cpu["cpustates"][value] += 1
365
+ when /core_id/
366
+ cpu[instance]["core_id"] = value
367
+ # Detect hyperthreading/multithreading
368
+ cpucores.push(value) if cpucores.index(value).nil?
369
+ when /family|fpu_type|model|stepping|vendor_id/
370
+ cpu[instance][key] = value
371
+ end
372
+ end
373
+ cpu["cores"] = cpucores.size
374
+ cpu["corethreads"] = (cpu["total"] / cpucores.size)
375
+ cpu["sockets"] = cpusockets.size
376
+ cpu["real"] = cpusockets.size
377
+ end
378
+
379
+ collect_data(:windows) do
380
+ require "wmi-lite/wmi"
381
+
382
+ cpu Mash.new
383
+ cores = 0
384
+ logical_processors = 0
385
+
386
+ wmi = WmiLite::Wmi.new
387
+ processors = wmi.instances_of("Win32_Processor")
388
+
389
+ processors.each_with_index do |processor, index|
390
+ current_cpu = index.to_s
391
+ cpu[current_cpu] = Mash.new
392
+
393
+ cpu[current_cpu]["cores"] = processor["numberofcores"]
394
+ cores += processor["numberofcores"]
395
+
396
+ logical_processors += processor["numberoflogicalprocessors"]
397
+ cpu[current_cpu]["vendor_id"] = processor["manufacturer"]
398
+ cpu[current_cpu]["family"] = processor["family"].to_s
399
+ cpu[current_cpu]["model"] = processor["revision"].to_s
400
+ cpu[current_cpu]["stepping"] = if processor["stepping"].nil?
401
+ processor["description"].match(/Stepping\s+(\d+)/)[1]
402
+ else
403
+ processor["stepping"]
404
+ end
405
+ cpu[current_cpu]["physical_id"] = processor["deviceid"]
406
+ cpu[current_cpu]["model_name"] = processor["name"]
407
+ cpu[current_cpu]["description"] = processor["description"]
408
+ cpu[current_cpu]["mhz"] = processor["maxclockspeed"].to_s
409
+ cpu[current_cpu]["cache_size"] = "#{processor['l2cachesize']} KB"
410
+ end
411
+
412
+ cpu[:total] = logical_processors
413
+ cpu[:cores] = cores
414
+ cpu[:real] = processors.length
415
+ end
416
+ end