ohai 16.10.6 → 17.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 586f4b057af4307f5fb1abd420939bdb2320dade9b63723fbbcc58135a645a9b
4
- data.tar.gz: b2c45c824a6ef7d69702f365f3e4d24bafe53b03afbfe0911e4bca8484556ad4
3
+ metadata.gz: 3e30d1da39ec42887fd2cb097f22f5cfeb0662275c11abe0a5b647f317f9a44b
4
+ data.tar.gz: 92330832131633f2c132857481898d6e3a0f3f966bfc122d91f33b416e400c1f
5
5
  SHA512:
6
- metadata.gz: 1e9e3ef34974d09ee07eb5c492a9e80028ea8d80c6afa38e86921de16f6a1f85884bb032129fe8322b0bb1942d9447012f3f89f7d027591feecd82a8211a389a
7
- data.tar.gz: 01fa6b22eee2fdfbead5f062efb6d346fc508b5b375edcddba0d56ed41c107b6a168e7532c573195b39f3a9b1ccdb24a67a3f914c056d2bedf88f1ac3e8aabe4
6
+ metadata.gz: 5ac054f71a2c0fae3566af336a08de3b5277c3bf7fc2e7c7fee076eb949018aba6aed602b28deffd9d97c6a543cb2cafefc42af0d820f6eaaa688e38867842d6
7
+ data.tar.gz: 0b63b2a16cb614b7c33e90decce218654e1d92ce6a394a041dd8a906ce18ac65fda3028fdfd1523dc145d4ab7f3af8d868f3950384e2cc36d186c57d25478af4
data/Gemfile CHANGED
@@ -4,19 +4,19 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  # pull these gems from master of chef/chef so that we're testing against what we will release
7
- gem "chef-config", git: "https://github.com/chef/chef", branch: "chef-16", glob: "chef-config/chef-config.gemspec"
8
- gem "chef-utils", git: "https://github.com/chef/chef", branch: "chef-16", glob: "chef-utils/chef-utils.gemspec"
7
+ gem "chef-config", git: "https://github.com/chef/chef", branch: "master", glob: "chef-config/chef-config.gemspec"
8
+ gem "chef-utils", git: "https://github.com/chef/chef", branch: "master", glob: "chef-utils/chef-utils.gemspec"
9
9
 
10
10
  # NOTE: do not submit PRs to add pry as a dep, add to your Gemfile.local
11
11
  group :development do
12
- gem "chefstyle", "1.6.2"
12
+ gem "chefstyle", git: "https://github.com/chef/chefstyle.git", branch: "master"
13
13
  gem "ipaddr_extensions"
14
14
  gem "rake", ">= 10.1.0"
15
15
  gem "rspec-collection_matchers", "~> 1.0"
16
16
  gem "rspec-core", "~> 3.0"
17
17
  gem "rspec-expectations", "~> 3.0"
18
18
  gem "rspec-mocks", "~> 3.0"
19
- gem "rubocop-performance", "1.9.2"
19
+ gem "rubocop-performance", "1.10.2"
20
20
  gem "rubocop-rspec"
21
21
  end
22
22
 
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Author:: Tim Smith (<tsmith@chef.io>)
4
+ # Copyright:: Copyright (c) Chef Software Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require "net/http" unless defined?(Net::HTTP)
20
+
21
+ module Ohai
22
+ module Mixin
23
+ #
24
+ # This code parses the Alibaba Instance Metadata API to provide details
25
+ # of the running instance.
26
+ #
27
+ # Note: As of 2021-02-07 there is only one API release so we're not implementing
28
+ # logic like the ec2 or azure mixins where we have to find the latest supported
29
+ # release
30
+ module AlibabaMetadata
31
+
32
+ ALI_METADATA_ADDR ||= "100.100.100.200"
33
+
34
+ def http_get(uri)
35
+ conn = Net::HTTP.start(ALI_METADATA_ADDR)
36
+ conn.read_timeout = 6
37
+ conn.keep_alive_timeout = 6
38
+ conn.get("/2016-01-01/#{uri}", { "User-Agent" => "chef-ohai/#{Ohai::VERSION}" })
39
+ end
40
+
41
+ def fetch_metadata(id = "")
42
+ response = http_get(id)
43
+ return nil unless response.code == "200"
44
+
45
+ if json?(response.body)
46
+ data = String(response.body)
47
+ parser = FFI_Yajl::Parser.new
48
+ parser.parse(data)
49
+ elsif response.body.include?("\n")
50
+ temp = {}
51
+ response.body.split("\n").each do |sub_attr|
52
+ temp[sanitize_key(sub_attr)] = fetch_metadata("#{id}/#{sub_attr}")
53
+ end
54
+ temp
55
+ else
56
+ response.body
57
+ end
58
+ end
59
+
60
+ # @param [String] data that might be JSON
61
+ #
62
+ # @return [Boolean] is the data JSON or not?
63
+ def json?(data)
64
+ data = String(data)
65
+ parser = FFI_Yajl::Parser.new
66
+ begin
67
+ parser.parse(data)
68
+ true
69
+ rescue FFI_Yajl::ParseError
70
+ false
71
+ end
72
+ end
73
+
74
+ # @param data [String]
75
+ #
76
+ # @return [Boolean] is there a trailing /?
77
+ def has_trailing_slash?(data)
78
+ !!( data =~ %r{/$} )
79
+ end
80
+
81
+ def sanitize_key(key)
82
+ key.gsub(%r{\-|/}, "_")
83
+ end
84
+ end
85
+ end
86
+ end
@@ -24,14 +24,15 @@ Ohai.plugin(:Virtualization) do
24
24
  virtualization Mash.new
25
25
 
26
26
  lpar_no, lpar_name = shell_out("uname -L").stdout.split(nil, 2)
27
+ lpar_no = lpar_no.to_i
27
28
 
28
- unless lpar_no.to_i == -1 || (lpar_no.to_i == 1 && lpar_name == "NULL")
29
+ unless lpar_no == -1 || (lpar_no == 1 && lpar_name == "NULL")
29
30
  virtualization[:lpar_no] = lpar_no
30
31
  virtualization[:lpar_name] = lpar_name
31
32
  end
32
33
 
33
- wpar_no = shell_out("uname -W").stdout.strip
34
- if wpar_no.to_i > 0
34
+ wpar_no = shell_out("uname -W").stdout.strip.to_i
35
+ if wpar_no > 0
35
36
  virtualization[:wpar_no] = wpar_no
36
37
  else
37
38
  # the below parses the output of lswpar in the long format
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Author:: Tim Smith (<tsmith@chef.io>)
4
+ # Copyright:: Copyright (c) Chef Software Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ # How we detect Alibaba from easiest to hardest & least reliable
20
+ # 1. Ohai alibaba hint exists. This always works
21
+ # 2. DMI sys_vendor data mentions alibaba.
22
+
23
+ Ohai.plugin(:Alibaba) do
24
+ require_relative "../mixin/alibaba_metadata"
25
+ require_relative "../mixin/http_helper"
26
+
27
+ include Ohai::Mixin::AlibabaMetadata
28
+ include Ohai::Mixin::HttpHelper
29
+
30
+ provides "alibaba"
31
+
32
+ # look for alibaba string in dmi sys_vendor data within the sys tree.
33
+ # this works even if the system lacks dmidecode use by the Dmi plugin
34
+ # @return [Boolean] do we have Alibaba DMI data?
35
+ def has_ali_dmi?
36
+ if /Alibaba/.match?(file_val_if_exists("/sys/class/dmi/id/sys_vendor"))
37
+ logger.trace("Plugin Alibaba: has_ali_dmi? == true")
38
+ true
39
+ else
40
+ logger.trace("Plugin Alibaba: has_ali_dmi? == false")
41
+ false
42
+ end
43
+ end
44
+
45
+ # return the contents of a file if the file exists
46
+ # @param path[String] abs path to the file
47
+ # @return [String] contents of the file if it exists
48
+ def file_val_if_exists(path)
49
+ if file_exist?(path)
50
+ file_read(path)
51
+ end
52
+ end
53
+
54
+ # a single check that combines all the various detection methods for Alibaba
55
+ # @return [Boolean] Does the system appear to be on Alibaba
56
+ def looks_like_alibaba?
57
+ return true if hint?("alibaba") || has_ali_dmi?
58
+ end
59
+
60
+ collect_data do
61
+ if looks_like_alibaba?
62
+ logger.trace("Plugin Alibaba: looks_like_alibaba? == true")
63
+ alibaba Mash.new
64
+ fetch_metadata.each do |k, v|
65
+ alibaba[k] = v
66
+ end
67
+ else
68
+ logger.trace("Plugin Alibaba: looks_like_alibaba? == false")
69
+ false
70
+ end
71
+ end
72
+ end
@@ -85,14 +85,12 @@ Ohai.plugin(:C) do
85
85
 
86
86
  def collect_glibc
87
87
  # glibc
88
- ["/lib/libc.so.6", "/lib64/libc.so.6"].each do |glibc|
89
- collect( Ohai.abs_path( glibc )) do |so|
90
- description = so.stdout.split($/).first
91
- if description =~ /(\d+\.\d+\.?\d*)/
92
- @c[:glibc] = Mash.new
93
- @c[:glibc][:version] = $1
94
- @c[:glibc][:description] = description
95
- end
88
+ collect("ldd --version") do |so|
89
+ description = so.stdout.split($/).first
90
+ if description =~ /(\d+\.\d+\.?\d*)/
91
+ @c[:glibc] = Mash.new
92
+ @c[:glibc][:version] = $1
93
+ @c[:glibc][:description] = description
96
94
  end
97
95
  end
98
96
  end
@@ -20,9 +20,19 @@
20
20
  Ohai.plugin(:Chef) do
21
21
  provides "chef_packages/chef"
22
22
 
23
+ def chef_effortless?
24
+ # Determine if client is being run as a Habitat package.
25
+ if Chef::CHEF_ROOT.include?("hab/pkgs/chef/chef")
26
+ # Determine if client is running in zero mode which would show it is using the Effortless pattern.
27
+ # Explicitly set response to true or nil, not false
28
+ ChefConfig::Config["chef_server_url"].include?("chefzero://")
29
+ end
30
+ end
31
+
23
32
  collect_data(:default, :target) do
24
33
  begin
25
34
  require "chef/version"
35
+ require "chef-config/config" unless defined?(ChefConfig::Config)
26
36
  rescue Gem::LoadError
27
37
  logger.trace("Plugin Chef: Unable to load the chef gem to determine the version")
28
38
  # this catches when you've done a major version bump of ohai, but
@@ -35,5 +45,6 @@ Ohai.plugin(:Chef) do
35
45
  chef_packages[:chef] = Mash.new
36
46
  chef_packages[:chef][:version] = Chef::VERSION
37
47
  chef_packages[:chef][:chef_root] = Chef::CHEF_ROOT
48
+ chef_packages[:chef][:chef_effortless] = chef_effortless?
38
49
  end
39
50
  end
@@ -18,6 +18,7 @@
18
18
  Ohai.plugin(:Cloud) do
19
19
  provides "cloud"
20
20
 
21
+ depends "alibaba"
21
22
  depends "ec2"
22
23
  depends "gce"
23
24
  depends "rackspace"
@@ -118,7 +119,22 @@ Ohai.plugin(:Cloud) do
118
119
  end
119
120
  end
120
121
 
121
- #---------------------------------------
122
+ #--------------------------------------
123
+ # Alibaba Cloud
124
+ #--------------------------------------
125
+
126
+ def on_alibaba?
127
+ alibaba != nil
128
+ end
129
+
130
+ def get_alibaba_values
131
+ @cloud_attr_obj.add_ipv4_addr(alibaba["meta_data"]["eipv4"], :public)
132
+ @cloud_attr_obj.add_ipv4_addr(alibaba["meta_data"]["private_ipv4"], :private)
133
+ @cloud_attr_obj.local_hostname = alibaba["meta_data"]["hostname"]
134
+ @cloud_attr_obj.provider = "alibaba"
135
+ end
136
+
137
+ #--------------------------------------
122
138
  # Google Compute Engine (gce)
123
139
  #--------------------------------------
124
140
 
@@ -133,9 +149,9 @@ Ohai.plugin(:Cloud) do
133
149
  end
134
150
  end.flatten.compact
135
151
 
136
- private_ips = gce["instance"]["networkInterfaces"].collect do |interface|
152
+ private_ips = gce["instance"]["networkInterfaces"].filter_map do |interface|
137
153
  interface["ip"]
138
- end.compact
154
+ end
139
155
 
140
156
  public_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :public) }
141
157
  private_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :private) }
@@ -334,6 +350,7 @@ Ohai.plugin(:Cloud) do
334
350
  get_azure_values if on_azure?
335
351
  get_digital_ocean_values if on_digital_ocean?
336
352
  get_softlayer_values if on_softlayer?
353
+ get_alibaba_values if on_alibaba?
337
354
 
338
355
  cloud @cloud_attr_obj.cloud_mash
339
356
  end
@@ -9,6 +9,7 @@
9
9
  # Author:: Prabhu Das (<prabhu.das@clogeny.com>)
10
10
  # Author:: Isa Farnik (<isa@chef.io>)
11
11
  # Author:: Doug MacEachern <dougm@vmware.com>
12
+ # Author:: Lance Albertson <lance@osuosl.org>
12
13
  # Copyright:: Copyright (c) Chef Software Inc.
13
14
  # License:: Apache License, Version 2.0
14
15
  #
@@ -46,13 +47,213 @@ Ohai.plugin(:CPU) do
46
47
  cpuinfo
47
48
  end
48
49
 
49
- collect_data(:linux) do
50
+ # Convert a string that looks like range of CPUs to an array
51
+ # Given the following range: 1-7
52
+ # Convert it into an array: [1, 2, 3, 4, 5, 6, 7]
53
+ def range_str_to_a(range)
54
+ range.split(",").each_with_object([]) do |cpu, arr|
55
+ if /\d+-\d+/.match?(cpu.to_s)
56
+ arr << Range.new(*cpu.split("-").map(&:to_i)).to_a
57
+ else
58
+ arr << cpu.to_i
59
+ end
60
+ end.flatten
61
+ end
62
+
63
+ def parse_lscpu(cpu_info)
64
+ lscpu_info = Mash.new
65
+ begin
66
+ so = shell_out("lscpu")
67
+ cpu_cores = shell_out("lscpu -p=CPU,CORE,SOCKET")
68
+ if so.exitstatus == 0 && cpu_cores.exitstatus == 0
69
+ lscpu_info[:numa_node_cpus] = Mash.new
70
+ lscpu_info[:vulnerability] = Mash.new
71
+ so.stdout.each_line do |line|
72
+ case line
73
+ when /^Architecture:\s+(.+)/
74
+ lscpu_info[:architecture] = $1.to_s
75
+ when /^CPU op-mode\(s\):\s+(.+)/
76
+ lscpu_info[:cpu_opmodes] = $1.split(", ")
77
+ when /^Byte Order:\s+(.+)/
78
+ lscpu_info[:byte_order] = $1.downcase
79
+ when /^Address sizes:\s+(.+)/
80
+ lscpu_info[:address_sizes] = $1.split(", ")
81
+ when /^CPU\(s\):\s+(.+)/
82
+ lscpu_info[:cpus] = $1.to_i
83
+ when /^On-line CPU\(s\) list:\s+(.+)/
84
+ cpu_range = range_str_to_a($1)
85
+ if cpu_range == [0]
86
+ lscpu_info[:cpus_online] = 0
87
+ else
88
+ lscpu_info[:cpus_online] = cpu_range.length
89
+ end
90
+ when /^Off-line CPU\(s\) list:\s+(.+)/
91
+ cpu_range = range_str_to_a($1)
92
+ if cpu_range == [0]
93
+ lscpu_info[:cpus_offline] = 0
94
+ else
95
+ lscpu_info[:cpus_offline] = cpu_range.length
96
+ end
97
+ when /^Thread\(s\) per core:\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
98
+ lscpu_info[:threads_per_core] = $1.to_i
99
+ when /^Core\(s\) per socket:\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
100
+ lscpu_info[:cores_per_socket] = $1.to_i
101
+ when /^Socket\(s\):\s+(.+)/ # http://rubular.com/r/DIzmPtJFvK
102
+ lscpu_info[:sockets] = $1.to_i
103
+ when /^Socket\(s\) per book:\s+(.+)/
104
+ lscpu_info[:sockets_per_book] = $1.to_i
105
+ when /^Book\(s\) per drawer:\s+(.+)/
106
+ lscpu_info[:books_per_drawer] = $1.to_i
107
+ when /^Drawer\(s\):\s+(.+)/
108
+ lscpu_info[:drawers] = $1.to_i
109
+ when /^NUMA node\(s\):\s+(.+)/
110
+ lscpu_info[:numa_nodes] = $1.to_i
111
+ when /^Vendor ID:\s+(.+)/
112
+ lscpu_info[:vendor_id] = $1
113
+ when /^Machine type:\s+(.+)/
114
+ lscpu_info[:machine_type] = $1
115
+ when /^CPU family:\s+(.+)/
116
+ lscpu_info[:family] = $1
117
+ when /^Model:\s+(.+)/
118
+ lscpu_info[:model] = $1
119
+ when /^Model name:\s+(.+)/
120
+ lscpu_info[:model_name] = $1
121
+ when /^Stepping:\s+(.+)/
122
+ lscpu_info[:stepping] = $1
123
+ when /^CPU MHz:\s+(.+)/
124
+ lscpu_info[:mhz] = $1
125
+ when /^CPU static MHz:\s+(.+)/
126
+ lscpu_info[:mhz] = $1
127
+ when /^CPU max MHz:\s+(.+)/
128
+ lscpu_info[:mhz_max] = $1
129
+ when /^CPU min MHz:\s+(.+)/
130
+ lscpu_info[:mhz_min] = $1
131
+ when /^CPU dynamic MHz:\s+(.+)/
132
+ lscpu_info[:mhz_dynamic] = $1
133
+ when /^BogoMIPS:\s+(.+)/
134
+ lscpu_info[:bogomips] = $1
135
+ when /^Virtualization:\s+(.+)/
136
+ lscpu_info[:virtualization] = $1
137
+ when /^Virtualization type:\s+(.+)/
138
+ lscpu_info[:virtualization_type] = $1
139
+ when /^Hypervisor vendor:\s+(.+)/
140
+ lscpu_info[:hypervisor_vendor] = $1
141
+ when /^Dispatching mode:\s+(.+)/
142
+ lscpu_info[:dispatching_mode] = $1
143
+ when /^L1d cache:\s+(.+)/
144
+ lscpu_info[:l1d_cache] = $1
145
+ when /^L1i cache:\s+(.+)/
146
+ lscpu_info[:l1i_cache] = $1
147
+ when /^L2 cache:\s+(.+)/
148
+ lscpu_info[:l2_cache] = $1
149
+ when /^L2d cache:\s+(.+)/
150
+ lscpu_info[:l2d_cache] = $1
151
+ when /^L2i cache:\s+(.+)/
152
+ lscpu_info[:l2i_cache] = $1
153
+ when /^L3 cache:\s+(.+)/
154
+ lscpu_info[:l3_cache] = $1
155
+ when /^L4 cache:\s+(.+)/
156
+ lscpu_info[:l4_cache] = $1
157
+ when /^NUMA node(\d+) CPU\(s\):\s+(.+)/
158
+ numa_node = $1
159
+ cpus = $2
160
+ lscpu_info[:numa_node_cpus][numa_node] = range_str_to_a(cpus)
161
+ when /^Vulnerability (.+?):\s+(.+)/ # https://rubular.com/r/aKtSD1ypUlKbGm
162
+ name = $1.strip.downcase.tr(" ", "_")
163
+ description = $2.strip
164
+ lscpu_info[:vulnerability][name] = Mash.new
165
+ lscpu_info[:vulnerability][name] = description
166
+ when /^Flags:\s+(.+)/
167
+ lscpu_info[:flags] = $1.split(" ").sort
168
+ # flags are "features" on aarch64 and s390x so add it for backwards computability
169
+ lscpu_info[:features] = lscpu_info[:flags] if lscpu_info[:architecture].match?(/aarch64|s390x/)
170
+ end
171
+ end
172
+
173
+ case lscpu_info[:architecture]
174
+ when "s390x"
175
+ # Add data from /proc/cpuinfo that isn't available from lscpu
176
+ lscpu_info[:bogomips_per_cpu] = cpu_info[:bogomips_per_cpu]
177
+ lscpu_info[:version] = cpu_info["0"][:version]
178
+ lscpu_info[:identification] = cpu_info["0"][:identification]
179
+ lscpu_info[:machine] = cpu_info["0"][:machine]
180
+ lscpu_total = lscpu_info[:sockets_per_book] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core] * lscpu_info[:books_per_drawer] * lscpu_info[:drawers]
181
+ lscpu_real = lscpu_info[:sockets_per_book]
182
+ lscpu_cores = lscpu_info[:sockets_per_book] * lscpu_info[:cores_per_socket] * lscpu_info[:books_per_drawer] * lscpu_info[:drawers]
183
+ when "ppc64le"
184
+ # Add data from /proc/cpuinfo that isn't available from lscpu
185
+ lscpu_info[:timebase] = cpu_info[:timebase]
186
+ lscpu_info[:platform] = cpu_info[:platform]
187
+ lscpu_info[:machine_model] = cpu_info[:machine_model]
188
+ lscpu_info[:machine] = cpu_info[:machine]
189
+ lscpu_info[:firmware] = cpu_info[:firmware] if cpu_info[:firmware]
190
+ lscpu_info[:mmu] = cpu_info[:mmu] if cpu_info[:mmu]
191
+ lscpu_info[:mhz] = cpu_info["0"][:mhz]
192
+ lscpu_total = lscpu_info[:sockets] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core]
193
+ lscpu_real = lscpu_info[:sockets]
194
+ lscpu_cores = lscpu_info[:sockets] * lscpu_info[:cores_per_socket]
195
+ else
196
+ lscpu_total = lscpu_info[:sockets] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core]
197
+ lscpu_real = lscpu_info[:sockets]
198
+ lscpu_cores = lscpu_info[:sockets] * lscpu_info[:cores_per_socket]
199
+ end
200
+
201
+ # Enumerate cpus and fill out data to provide backwards compatibility data
202
+ cpu_cores.stdout.each_line do |line|
203
+ current_cpu = nil
204
+ current_core = nil
205
+ current_socket = nil
206
+
207
+ case line
208
+ # skip comments
209
+ when /^#/
210
+ next
211
+ # Parse data from "lscpu -p=CPU,CORE,SOCKET"
212
+ when /(\d+),(\d+),(\d+)/
213
+ current_cpu = $1
214
+ current_core = $2
215
+ current_socket = $3
216
+ end
217
+ lscpu_info[current_cpu] = Mash.new
218
+ lscpu_info[current_cpu][:vendor_id] = lscpu_info[:vendor_id] if lscpu_info[:vendor_id]
219
+ lscpu_info[current_cpu][:family] = lscpu_info[:family] if lscpu_info[:family]
220
+ lscpu_info[current_cpu][:model] = lscpu_info[:model] if lscpu_info[:model]
221
+ lscpu_info[current_cpu][:model_name] = lscpu_info[:model_name] if lscpu_info[:model_name]
222
+ lscpu_info[current_cpu][:stepping] = lscpu_info[:stepping] if lscpu_info[:stepping]
223
+ lscpu_info[current_cpu][:mhz] = lscpu_info[:mhz] if lscpu_info[:mhz]
224
+ lscpu_info[current_cpu][:bogomips] = lscpu_info[:bogomips] if lscpu_info[:bogomips]
225
+ # Per cpu cache_size is only really available from /proc/cpuinfo on x86
226
+ lscpu_info[current_cpu][:cache_size] = cpu_info[current_cpu][:cache_size] if cpu_info[current_cpu] && cpu_info[current_cpu][:cache_size]
227
+ lscpu_info[current_cpu][:physical_id] = current_socket
228
+ lscpu_info[current_cpu][:core_id] = current_core
229
+ lscpu_info[current_cpu][:cores] = lscpu_info[:cores_per_socket].to_s
230
+ lscpu_info[current_cpu][:flags] = lscpu_info[:flags] if lscpu_info[:flags]
231
+ lscpu_info[current_cpu][:features] = lscpu_info[:flags] if lscpu_info[:architecture].match?(/aarch64|s390x/)
232
+ if lscpu_info[:architecture] == "s390x"
233
+ lscpu_info[current_cpu][:version] = cpu_info[current_cpu][:version] if cpu_info[current_cpu][:version]
234
+ lscpu_info[current_cpu][:identification] = cpu_info[current_cpu][:identification] if cpu_info[current_cpu][:identification]
235
+ lscpu_info[current_cpu][:machine] = cpu_info[current_cpu][:machine] if cpu_info[current_cpu][:machine]
236
+ end
237
+ end
238
+ lscpu_info[:total] = lscpu_total
239
+ lscpu_info[:real] = lscpu_real
240
+ lscpu_info[:cores] = lscpu_cores
241
+ else
242
+ logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
243
+ end
244
+ rescue Ohai::Exceptions::Exec # util-linux isn't installed most likely
245
+ logger.trace("Plugin CPU: Error executing lscpu. util-linux may not be installed.")
246
+ end
247
+ lscpu_info
248
+ end
249
+
250
+ def parse_cpuinfo
50
251
  cpuinfo = Mash.new
51
252
  real_cpu = Mash.new
52
253
  cpu_number = 0
53
254
  current_cpu = nil
54
255
 
55
- file_open("/proc/cpuinfo").each do |line|
256
+ file_open("/proc/cpuinfo").each_line do |line|
56
257
  case line
57
258
  when /processor\s+:\s(.+)/
58
259
  cpuinfo[$1] = Mash.new
@@ -68,7 +269,11 @@ Ohai.plugin(:CPU) do
68
269
  when /cpu family\s+:\s(.+)/
69
270
  cpuinfo[current_cpu]["family"] = $1
70
271
  when /model\s+:\s(.+)/
71
- cpuinfo[current_cpu]["model"] = $1
272
+ model = $1
273
+ cpuinfo[current_cpu]["model"] = model
274
+ # ppc has "model" at the end of /proc/cpuinfo. In addition it should always include a include a dash or "IBM".
275
+ # So let's put this in cpu/model on ppc
276
+ cpuinfo["machine_model"] = model if model.match?(/-|IBM/)
72
277
  when /stepping\s+:\s(.+)/
73
278
  cpuinfo[current_cpu]["stepping"] = $1
74
279
  when /physical id\s+:\s(.+)/
@@ -94,6 +299,24 @@ Ohai.plugin(:CPU) do
94
299
  cpuinfo["bogomips_per_cpu"] = $1
95
300
  when /features\s+:\s(.+)/
96
301
  cpuinfo["features"] = $1.split
302
+ # ppc64le
303
+ when /revision\s+:\s(.+)/
304
+ cpuinfo[current_cpu]["model"] = $1
305
+ when /cpu\s+:\s(.+)/
306
+ cpuinfo[current_cpu]["model_name"] = $1
307
+ when /clock\s+:\s(.+)/
308
+ cpuinfo[current_cpu]["mhz"] = $1
309
+ when /timebase\s+:\s(.+)/
310
+ cpuinfo["timebase"] = $1
311
+ when /platform\s+:\s(.+)/
312
+ cpuinfo["platform"] = $1
313
+ when /machine\s+:\s(.+)/
314
+ cpuinfo["machine"] = $1
315
+ when /firmware\s+:\s(.+)/
316
+ cpuinfo["firmware"] = $1
317
+ when /MMU\s+:\s(.+)/
318
+ cpuinfo["mmu"] = $1
319
+ # s390x
97
320
  when /processor\s(\d):\s(.+)/
98
321
  current_cpu = $1
99
322
  cpu_number += 1
@@ -108,40 +331,28 @@ Ohai.plugin(:CPU) do
108
331
  end
109
332
  end
110
333
 
111
- cpu cpuinfo
112
-
113
- cpu[:total] = cpu_number
114
-
115
334
  # use data we collected unless cpuinfo is lacking core information
116
335
  # which is the case on older linux distros
117
- if !real_cpu.empty? && cpu["0"]["cores"]
118
- cpu[:real] = real_cpu.keys.length
119
- cpu[:cores] = real_cpu.keys.length * cpu["0"]["cores"].to_i
336
+ if !real_cpu.empty? && cpuinfo["0"]["cores"]
337
+ logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
338
+ cpuinfo[:real] = real_cpu.keys.length
339
+ cpuinfo[:cores] = real_cpu.keys.length * cpuinfo["0"]["cores"].to_i
120
340
  else
121
- begin
122
- logger.trace("Plugin CPU: Falling back to aggregate data from lscpu as real cpu & core data is missing in /proc/cpuinfo")
123
- so = shell_out("lscpu")
124
- if so.exitstatus == 0
125
- lscpu_data = Mash.new
126
- so.stdout.each_line do |line|
127
- case line
128
- when /^Thread\(s\) per core:\s(.+)/ # http://rubular.com/r/lOw2pRrw1q
129
- lscpu_data[:threads] = $1.to_i
130
- when /^Core\(s\) per socket:\s(.+)/ # http://rubular.com/r/lOw2pRrw1q
131
- lscpu_data[:cores] = $1.to_i
132
- when /^Socket\(s\):\s(.+)/ # http://rubular.com/r/DIzmPtJFvK
133
- lscpu_data[:sockets] = $1.to_i
134
- end
135
- end
136
- cpu[:total] = lscpu_data[:sockets] * lscpu_data[:cores] * lscpu_data[:threads]
137
- cpu[:real] = lscpu_data[:sockets]
138
- cpu[:cores] = lscpu_data[:sockets] * lscpu_data[:cores]
139
- else
140
- logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
141
- end
142
- rescue Ohai::Exceptions::Exec # util-linux isn't installed most likely
143
- logger.trace("Plugin CPU: Error executing lscpu. util-linux may not be installed.")
144
- end
341
+ logger.trace("Plugin CPU: real cpu & core data is missing in /proc/cpuinfo and lscpu")
342
+ end
343
+ cpuinfo[:total] = cpu_number
344
+ cpuinfo
345
+ end
346
+
347
+ collect_data(:linux) do
348
+ cpuinfo = parse_cpuinfo
349
+ lscpu = parse_lscpu(cpuinfo)
350
+
351
+ # If we don't have any data from lscpu then get it from /proc/cpuinfo
352
+ if lscpu.empty?
353
+ cpu cpuinfo
354
+ else
355
+ cpu lscpu
145
356
  end
146
357
  end
147
358