ohai 15.12.0 → 16.0.20

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cc502163cd1c79f43b4b934c425a00b2b00c2626cefb82882659fa4756dd82f
4
- data.tar.gz: 2eadca5148f5f1c0706157f3b2c7c2cfe6606c304f249815c418aba69ca87c53
3
+ metadata.gz: 474ba3761494212a1559a82eb0fea84b9ec142762b53cdb4625a6b0d3bf1a9e8
4
+ data.tar.gz: a809312e61ca2626c073c64e95043c053c6a49bb524e758a6d219345377aadbb
5
5
  SHA512:
6
- metadata.gz: d3e0b6ae3e18c740ca5e30db4d4db8200c1cae7b742bd5cdda9541c05cc30e8d0570250b86b51dc5397cd8cc383d63d82240ffb5bb069ce9457b536a6c87dfed
7
- data.tar.gz: 3925101539b829009b8215eddaccb20d6b88c791ee69224cddd7d4c824bc5939dab97352e97184183d8f1561b3a14108187370e37ac006869cbc8cceae7ce4f2
6
+ metadata.gz: e12e1ef3e93b78b95c6482cc5d9a4a192cd1759b4021ae2a9a11422f0ea50adaea2f739c6baccaa87dd61d3b97c7ced7204944452a5d97eee0c386d52b9ef60c
7
+ data.tar.gz: 8cdb5bbcc612d1f4c19b4193f385a62769c0e3d06e4e1eb3aa6f7d8cc4a9acfcb23d3f175faf7c4f6e7e684cbf47af582afef5df54596e62489edb27453991e1
data/Gemfile CHANGED
@@ -2,8 +2,9 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
+ # NOTE: do not submit PRs to add pry as a dep, add to your Gemfile.local
5
6
  group :development do
6
- gem "chefstyle", "~> 1.0"
7
+ gem "chefstyle", git: "https://github.com/chef/chefstyle.git", branch: "master"
7
8
  gem "rake", ">= 10.1.0"
8
9
  gem "rspec-core", "~> 3.0"
9
10
  gem "rspec-expectations", "~> 3.0"
@@ -12,10 +13,6 @@ group :development do
12
13
  gem "ipaddr_extensions"
13
14
  end
14
15
 
15
- group :ci do
16
- gem "rspec_junit_formatter"
17
- end
18
-
19
16
  group :docs do
20
17
  gem "yard"
21
18
  gem "redcarpet"
@@ -25,6 +22,6 @@ end
25
22
  group :debug do
26
23
  gem "pry"
27
24
  gem "pry-byebug"
28
- gem "pry-stack_explorer", "~> 0.4.0" # pin until we drop ruby < 2.6
25
+ gem "pry-stack_explorer"
29
26
  gem "rb-readline"
30
27
  end
@@ -111,6 +111,15 @@ module Ohai
111
111
  id
112
112
  end
113
113
 
114
+ SKIPPED_CONVENIENCE_KEYS = %w{
115
+ application_identifier
116
+ caption
117
+ creation_class_name
118
+ size
119
+ system_creation_class_name
120
+ record_id
121
+ }.freeze
122
+
114
123
  # create simplified convenience access keys for each record type
115
124
  # for single occurrences of one type, copy to top level all fields and values
116
125
  # for multiple occurrences of same type, copy to top level all fields and values that are common to all records
@@ -122,13 +131,12 @@ module Ohai
122
131
 
123
132
  records[:all_records].each do |record|
124
133
  record.each do |field, value|
125
- next if value.is_a?(Mash)
126
- next if field.to_s == "application_identifier"
127
- next if field.to_s == "size"
128
- next if field.to_s == "record_id"
134
+ next unless value.is_a?(String)
129
135
 
130
136
  translated = field.downcase.gsub(/[^a-z0-9]/, "_")
131
- value = value.strip
137
+ next if SKIPPED_CONVENIENCE_KEYS.include?(translated.to_s)
138
+
139
+ value = value.strip
132
140
  if in_common.key?(translated)
133
141
  in_common[translated] = nil unless in_common[translated] == value
134
142
  else
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Tim Smith (<tsmith@chef.io>)
3
- # Copyright:: Copyright 2017 Chef Software, Inc.
3
+ # Copyright:: 2017-2020 Chef Software, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,30 +19,86 @@ require "net/http" unless defined?(Net::HTTP)
19
19
 
20
20
  module Ohai
21
21
  module Mixin
22
+ #
23
+ # This code parses the Azure Instance Metadata API to provide details
24
+ # of the running instance.
25
+ #
26
+ # The code probes the instance metadata endpoint for
27
+ # available versions, determines the most advanced version known to
28
+ # work and executes the metadata retrieval using that version.
29
+ #
30
+ # If no compatible version is found, an empty hash is returned.
31
+ #
22
32
  module AzureMetadata
23
33
 
24
34
  AZURE_METADATA_ADDR ||= "169.254.169.254".freeze
25
- AZURE_METADATA_URL ||= "/metadata/instance?api-version=2017-08-01".freeze
26
35
 
27
- # fetch the meta content with a timeout and the required header
36
+ # it's important that the newer versions are at the end of this array so we can skip sorting it
37
+ AZURE_SUPPORTED_VERSIONS ||= %w{ 2017-04-02 2017-08-01 2017-12-01 2018-02-01 2018-04-02
38
+ 2018-10-01 2019-02-01 2019-03-11 2019-04-30 2019-06-01
39
+ 2019-06-04 2019-08-01 2019-08-15 2019-11-01 }.freeze
40
+
41
+ def best_api_version
42
+ @api_version ||= begin
43
+ logger.trace("Mixin AzureMetadata: Fetching http://#{AZURE_METADATA_ADDR}/metadata/instance to determine the latest supported metadata release")
44
+ response = http_get("/metadata/instance")
45
+ if response.code == "404"
46
+ logger.trace("Mixin AzureMetadata: Received HTTP 404 from metadata server while determining API version, assuming #{AZURE_SUPPORTED_VERSIONS.last}")
47
+ return AZURE_SUPPORTED_VERSIONS.last
48
+ elsif response.code != "400" # 400 is actually what we want
49
+ raise "Mixin AzureMetadata: Unable to determine Azure metadata version (returned #{response.code} response)"
50
+ end
51
+
52
+ # azure returns a list of the 3 latest versions it supports
53
+ versions = parse_json(response.body).fetch("newest-versions", [])
54
+ versions.sort!
55
+
56
+ until versions.empty? || AZURE_SUPPORTED_VERSIONS.include?(versions.last)
57
+ pv = versions.pop
58
+ logger.trace("Mixin AzureMetadata: Azure metadata version #{pv} is not present in the versions provided by the Azure Instance Metadata service")
59
+ end
60
+
61
+ if versions.empty?
62
+ logger.debug "Mixin AzureMetadata: The short list of supported versions provided by Azure Instance Metadata service doesn't match any known versions to Ohai. Using the latest supported release known to Ohai instead: #{AZURE_SUPPORTED_VERSIONS.last}"
63
+ return AZURE_SUPPORTED_VERSIONS.last
64
+ end
65
+
66
+ logger.trace("Mixin AzureMetadata: Latest supported Azure metadata version: #{versions.last}")
67
+ versions.last
68
+ end
69
+ end
70
+
71
+ # fetch the meta content with a timeout and the required header and a read timeout of 6s
72
+ #
73
+ # @param [String] the relative uri to fetch from the Azure Metadata Service URL
74
+ #
75
+ # @return [Net::HTTP]
28
76
  def http_get(uri)
29
77
  conn = Net::HTTP.start(AZURE_METADATA_ADDR)
30
78
  conn.read_timeout = 6
31
79
  conn.get(uri, { "Metadata" => "true" })
32
80
  end
33
81
 
34
- def fetch_metadata
35
- logger.trace("Mixin AzureMetadata: Fetching metadata from host #{AZURE_METADATA_ADDR} at #{AZURE_METADATA_URL}")
36
- response = http_get(AZURE_METADATA_URL)
82
+ # parse JSON data from a String to a Hash
83
+ #
84
+ # @param [String] response_body json as string to parse
85
+ #
86
+ # @return [Hash]
87
+ def parse_json(response_body)
88
+ data = String(response_body)
89
+ parser = FFI_Yajl::Parser.new
90
+ parser.parse(data)
91
+ rescue FFI_Yajl::ParseError
92
+ logger.warn("Mixin AzureMetadata: Metadata response is NOT valid JSON")
93
+ nil
94
+ end
95
+
96
+ def fetch_metadata(api_version = nil)
97
+ metadata_url = "/metadata/instance?api-version=#{best_api_version}"
98
+ logger.trace("Mixin AzureMetadata: Fetching metadata from host #{AZURE_METADATA_ADDR} at #{metadata_url}")
99
+ response = http_get(metadata_url)
37
100
  if response.code == "200"
38
- begin
39
- data = StringIO.new(response.body)
40
- parser = FFI_Yajl::Parser.new
41
- parser.parse(data)
42
- rescue FFI_Yajl::ParseError
43
- logger.warn("Mixin AzureMetadata: Metadata response is NOT valid JSON")
44
- nil
45
- end
101
+ parse_json(response.body)
46
102
  else
47
103
  logger.warn("Mixin AzureMetadata: Received response code #{response.code} requesting metadata")
48
104
  nil
@@ -160,7 +160,7 @@ module Ohai
160
160
  if key[-1..-1] != "/"
161
161
  retr_meta = metadata_get("#{id}#{key}", api_version)
162
162
  data = retr_meta ? retr_meta : ""
163
- json = StringIO.new(data)
163
+ json = String(data)
164
164
  parser = FFI_Yajl::Parser.new
165
165
  metadata[metadata_key(key)] = parser.parse(json)
166
166
  elsif not key.eql?("/")
@@ -39,7 +39,7 @@ module Ohai
39
39
  return nil unless response.code == "200"
40
40
 
41
41
  if json?(response.body)
42
- data = StringIO.new(response.body)
42
+ data = String(response.body)
43
43
  parser = FFI_Yajl::Parser.new
44
44
  parser.parse(data)
45
45
  elsif has_trailing_slash?(id) || (id == "")
@@ -57,7 +57,7 @@ module Ohai
57
57
  #
58
58
  # @return [Boolean] is the data JSON or not?
59
59
  def json?(data)
60
- data = StringIO.new(data)
60
+ data = String(data)
61
61
  parser = FFI_Yajl::Parser.new
62
62
  begin
63
63
  parser.parse(data)
@@ -36,10 +36,10 @@ Ohai.plugin(:C) do
36
36
  so = shell_out("/usr/bin/xcode-select -p")
37
37
  if so.exitstatus == 0
38
38
  logger.trace("Plugin C: Xcode Command Line Tools found.")
39
- return true
39
+ true
40
40
  else
41
41
  logger.trace("Plugin C: Xcode Command Line Tools not found.")
42
- return false
42
+ false
43
43
  end
44
44
  rescue Ohai::Exceptions::Exec
45
45
  logger.trace("Plugin C: xcode-select binary could not be found. Skipping data.")
@@ -41,8 +41,8 @@ Ohai.plugin(:Hardware) do
41
41
  hardware.merge!(hw_hash[0]["_items"][0])
42
42
 
43
43
  # ProductName: Mac OS X
44
- # ProductVersion: 10.15.6
45
- # BuildVersion: 19G46c
44
+ # ProductVersion: 10.12.5
45
+ # BuildVersion: 16F73
46
46
  shell_out("sw_vers").stdout.lines.each do |line|
47
47
  case line
48
48
  when /^ProductName:\s*(.*)$/
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@chef.io>)
3
- # Copyright:: Copyright (c) Chef Software, Inc.
3
+ # Copyright:: Copyright (c) 2008-2016 Chef Software, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,6 +23,11 @@ Ohai.plugin(:Platform) do
23
23
  so = shell_out((Ohai.abs_path( "/usr/bin/sw_vers" )).to_s)
24
24
  so.stdout.lines do |line|
25
25
  case line
26
+ when /^ProductName:\s+(.+)$/
27
+ macname = $1
28
+ macname.downcase!
29
+ macname.tr!(" ", "_")
30
+ platform macname
26
31
  when /^ProductVersion:\s+(.+)$/
27
32
  platform_version $1
28
33
  when /^BuildVersion:\s+(.+)$/
@@ -30,8 +35,6 @@ Ohai.plugin(:Platform) do
30
35
  end
31
36
  end
32
37
 
33
- # if we're on darwin assume we're on mac_os_x
34
- platform "mac_os_x"
35
38
  platform_family "mac_os_x"
36
39
  end
37
40
  end
@@ -24,7 +24,7 @@ Ohai.plugin(:Docker) do
24
24
  def docker_info_json
25
25
  so = shell_out("docker info --format '{{json .}}'")
26
26
  if so.exitstatus == 0
27
- return JSON.parse(so.stdout)
27
+ JSON.parse(so.stdout)
28
28
  end
29
29
  rescue Ohai::Exceptions::Exec
30
30
  logger.trace('Plugin Docker: Could not shell_out "docker info --format \'{{json .}}\'". Skipping plugin')
@@ -86,7 +86,7 @@ Ohai.plugin(:EC2) do
86
86
  wmi = WmiLite::Wmi.new
87
87
  if wmi.first_of("Win32_ComputerSystemProduct")["identifyingnumber"] =~ /^ec2/
88
88
  logger.trace("Plugin EC2: has_ec2_identifying_number? == true")
89
- return true
89
+ true
90
90
  end
91
91
  else
92
92
  logger.trace("Plugin EC2: has_ec2_identifying_number? == false")
@@ -32,9 +32,9 @@ Ohai.plugin(:Eucalyptus) do
32
32
  def get_mac_address(addresses)
33
33
  detected_addresses = addresses.detect { |address, keypair| keypair == { "family" => "lladdr" } }
34
34
  if detected_addresses
35
- return detected_addresses.first
35
+ detected_addresses.first
36
36
  else
37
- return ""
37
+ ""
38
38
  end
39
39
  end
40
40
 
@@ -6,7 +6,7 @@
6
6
  # Author:: Prabhu Das (<prabhu.das@clogeny.com>)
7
7
  # Author:: Isa Farnik (<isa@chef.io>)
8
8
  # Author:: James Gartrell (<jgartrel@gmail.com>)
9
- # Copyright:: Copyright (c) 2008-2017 Chef Software, Inc.
9
+ # Copyright:: Copyright (c) 2008-2020 Chef Software, Inc.
10
10
  # Copyright:: Copyright (c) 2015 Facebook, Inc.
11
11
  # License:: Apache License, Version 2.0
12
12
  #
@@ -23,6 +23,8 @@
23
23
  # limitations under the License.
24
24
  #
25
25
 
26
+ require "set"
27
+
26
28
  Ohai.plugin(:Filesystem) do
27
29
  provides "filesystem"
28
30
 
@@ -98,15 +100,6 @@ Ohai.plugin(:Filesystem) do
98
100
  view
99
101
  end
100
102
 
101
- def generate_deprecated_view(fs)
102
- view = generate_device_view(fs)
103
- view.each do |device, entry|
104
- view[device][:mount] = entry[:mounts].first
105
- view[device].delete(:mounts)
106
- end
107
- view
108
- end
109
-
110
103
  def generate_deprecated_windows_view(fs)
111
104
  view = generate_mountpoint_view(fs)
112
105
  view.each do |mp, entry|
@@ -115,22 +108,6 @@ Ohai.plugin(:Filesystem) do
115
108
  view
116
109
  end
117
110
 
118
- def generate_deprecated_solaris_view(fs, old_zfs)
119
- view = generate_deprecated_view(fs)
120
- old_zfs.each do |fsname, attributes|
121
- view[fsname] ||= Mash.new
122
- view[fsname][:fs_type] = "zfs"
123
- view[fsname][:mount] = attributes[:values][:mountpoint] if attributes[:values].key?("mountpoint")
124
- view[fsname][:device] = fsname
125
- view[fsname][:zfs_values] = attributes[:values]
126
- view[fsname][:zfs_sources] = attributes[:sources]
127
- # parents will already be here
128
- # but we want to nuke "zfs_properties"
129
- view[fsname].delete("zfs_properties")
130
- end
131
- view
132
- end
133
-
134
111
  def parse_common_df(out)
135
112
  fs = {}
136
113
  out.each_line do |line|
@@ -496,9 +473,8 @@ Ohai.plugin(:Filesystem) do
496
473
  fs_data["by_mountpoint"] = by_mountpoint
497
474
  fs_data["by_pair"] = by_pair
498
475
 
499
- # Set the filesystem data - BSD didn't do the conversion when everyone else
500
- # did, so 15 will have both be the new API and 16 will drop the old API
501
- filesystem generate_deprecated_view(fs)
476
+ # @todo in Chef 17 the filesystem2 part of this goes away
477
+ filesystem fs_data
502
478
  filesystem2 fs_data
503
479
  end
504
480
 
@@ -595,7 +571,6 @@ Ohai.plugin(:Filesystem) do
595
571
 
596
572
  # Grab any zfs data from "zfs get"
597
573
  zfs = Mash.new
598
- old_zfs = Mash.new
599
574
  zfs_get = "zfs get -p -H all"
600
575
  run_with_check("zfs") do
601
576
  so = shell_out(zfs_get)
@@ -612,13 +587,6 @@ Ohai.plugin(:Filesystem) do
612
587
  value: value,
613
588
  source: source,
614
589
  }
615
- # needed for old v1 view
616
- old_zfs[filesystem] ||= Mash.new
617
- old_zfs[filesystem][:values] ||= Mash.new
618
- old_zfs[filesystem][:sources] ||= Mash.new
619
- old_zfs[filesystem][:values][property] = value
620
- old_zfs[filesystem][:values][property] = value
621
- old_zfs[filesystem][:sources][property] = source
622
590
  end
623
591
  end
624
592
 
@@ -652,9 +620,8 @@ Ohai.plugin(:Filesystem) do
652
620
  fs_data["by_mountpoint"] = by_mountpoint
653
621
  fs_data["by_pair"] = by_pair
654
622
 
655
- # Set the filesystem data - Solaris didn't do the conversion when everyone
656
- # else did, so 15 will have both be the new API and 16 will drop the old API
657
- filesystem generate_deprecated_solaris_view(fs, old_zfs)
623
+ # @todo in Chef 17 the filesystem2 plugin goes away
624
+ filesystem fs_data
658
625
  filesystem2 fs_data
659
626
  end
660
627
 
@@ -745,9 +712,8 @@ Ohai.plugin(:Filesystem) do
745
712
  fs_data["by_mountpoint"] = by_mountpoint
746
713
  fs_data["by_pair"] = by_pair
747
714
 
748
- # Set the filesystem data - AIX didn't do the conversion when everyone
749
- # else did, so 15 will have both be the new API and 16 will drop the old API
750
- filesystem generate_deprecated_view(fs)
715
+ # @todo in Chef 17 the filesystem2 plugin goes away here
716
+ filesystem fs_data
751
717
  filesystem2 fs_data
752
718
  end
753
719
 
@@ -25,7 +25,7 @@
25
25
  Ohai.plugin(:Fips) do
26
26
  provides "fips"
27
27
 
28
- collect_data(:linux) do
28
+ collect_data(:linux, :windows) do
29
29
  fips Mash.new
30
30
 
31
31
  require "openssl" unless defined?(OpenSSL)
@@ -54,7 +54,7 @@ Ohai.plugin(:GCE) do
54
54
  computer_system = wmi.first_of("Win32_ComputerSystem")
55
55
  if computer_system["Manufacturer"] =~ /^Google/ && computer_system["Model"] =~ /^Google/
56
56
  logger.trace("Plugin GCE: has_gce_system_info? == true")
57
- return true
57
+ true
58
58
  end
59
59
  else
60
60
  logger.trace("Plugin GCE: has_gce_system_info? == false")
@@ -4,7 +4,7 @@
4
4
  # Author:: Bryan McLellan (<btm@loftninjas.org>)
5
5
  # Author:: Claire McQuin (<claire@chef.io>)
6
6
  # Author:: James Gartrell (<jgartrel@gmail.com>)
7
- # Copyright:: Copyright (c) Chef Software, Inc.
7
+ # Copyright:: Copyright (c) 2008-2018 Chef Software, Inc.
8
8
  # Copyright:: Copyright (c) 2009 Bryan McLellan
9
9
  # License:: Apache License, Version 2.0
10
10
  #
@@ -137,12 +137,11 @@ Ohai.plugin(:Kernel) do
137
137
  end
138
138
  end
139
139
 
140
- # see if a WMI name is in the blocked list so we can avoid writing
141
- # out useless data to ohai
142
- #
140
+ # see if a WMI name is blacklisted so we can avoid writing out
141
+ # useless data to ohai
143
142
  # @param [String] name the wmi name to check
144
- # @return [Boolean] is the wmi name in the blocked list
145
- def blocked_wmi_name?(name)
143
+ # @return [Boolean] is the wmi name blacklisted
144
+ def blacklisted_wmi_name?(name)
146
145
  [
147
146
  "creation_class_name", # this is just the wmi name
148
147
  "cs_creation_class_name", # this is just the wmi name
@@ -263,7 +262,7 @@ Ohai.plugin(:Kernel) do
263
262
  host = wmi.first_of("Win32_OperatingSystem")
264
263
  kernel[:os_info] = Mash.new
265
264
  host.wmi_ole_object.properties_.each do |p|
266
- next if blocked_wmi_name?(p.name.wmi_underscore)
265
+ next if blacklisted_wmi_name?(p.name.wmi_underscore)
267
266
 
268
267
  kernel[:os_info][p.name.wmi_underscore.to_sym] = host[p.name.downcase]
269
268
  end
@@ -278,7 +277,7 @@ Ohai.plugin(:Kernel) do
278
277
  kernel[:cs_info] = Mash.new
279
278
  host = wmi.first_of("Win32_ComputerSystem")
280
279
  host.wmi_ole_object.properties_.each do |p|
281
- next if blocked_wmi_name?(p.name.wmi_underscore)
280
+ next if blacklisted_wmi_name?(p.name.wmi_underscore)
282
281
 
283
282
  kernel[:cs_info][p.name.wmi_underscore.to_sym] = host[p.name.downcase]
284
283
  end
@@ -0,0 +1,83 @@
1
+ #
2
+ # Author:: Davide Cavalca <dcavalca@fb.com>
3
+ # Copyright:: Copyright (c) 2020 Facebook
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ Ohai.plugin(:Interrupts) do
20
+ depends "cpu"
21
+ provides "interrupts", "interrupts/irq", "interrupts/smp_affinity_by_cpu"
22
+ optional true
23
+
24
+ # Documentation: https://www.kernel.org/doc/Documentation/IRQ-affinity.txt
25
+ # format: comma-separate list of 32bit bitmask in hex
26
+ # each bit is a CPU, right to left ordering (i.e. CPU0 is rightmost)
27
+ def parse_smp_affinity(path, cpus)
28
+ masks = File.read(path).strip
29
+ bit_masks = []
30
+ masks.split(",").each do |mask|
31
+ bit_masks << mask.rjust(8, "0").to_i(16).to_s(2)
32
+ end
33
+ affinity_mask = bit_masks.join
34
+ affinity_by_cpu = affinity_mask.split("").reverse
35
+ smp_affinity_by_cpu = Mash.new
36
+ (0..cpus - 1).each do |cpu|
37
+ smp_affinity_by_cpu[cpu] = affinity_by_cpu[cpu].to_i == 1
38
+ end
39
+ smp_affinity_by_cpu
40
+ end
41
+
42
+ collect_data(:linux) do
43
+ interrupts Mash.new
44
+
45
+ cpus = cpu["total"]
46
+ interrupts[:smp_affinity_by_cpu] =
47
+ parse_smp_affinity("/proc/irq/default_smp_affinity", cpus)
48
+
49
+ interrupts[:irq] = Mash.new
50
+ File.open("/proc/interrupts").each do |line|
51
+ # Documentation: https://www.kernel.org/doc/Documentation/filesystems/proc.txt
52
+ # format is "{irqn}: {CPUn...} [type] [vector] [device]"
53
+ irqn, fields = line.split(":", 2)
54
+ # skip the header
55
+ next if fields.nil?
56
+
57
+ irqn.strip!
58
+ Ohai::Log.debug("irq: processing #{irqn}")
59
+
60
+ interrupts[:irq][irqn] = Mash.new
61
+ interrupts[:irq][irqn][:events_by_cpu] = Mash.new
62
+
63
+ fields = fields.split(nil, cpus + 1)
64
+ (0..cpus - 1).each do |cpu|
65
+ interrupts[:irq][irqn][:events_by_cpu][cpu] = fields[cpu].to_i
66
+ end
67
+ # Only regular IRQs have extra fields and affinity settings
68
+ if /^\d+$/.match(irqn)
69
+ interrupts[:irq][irqn][:type],
70
+ interrupts[:irq][irqn][:vector],
71
+ interrupts[:irq][irqn][:device] =
72
+ fields[cpus].split
73
+ if File.exist?("/proc/irq/#{irqn}/smp_affinity")
74
+ interrupts[:irq][irqn][:smp_affinity_by_cpu] =
75
+ parse_smp_affinity("/proc/irq/#{irqn}/smp_affinity", cpus)
76
+ end
77
+ # ERR and MIS do not have any extra fields
78
+ elsif fields[cpus]
79
+ interrupts[:irq][irqn][:type] = fields[cpus].strip
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,51 @@
1
+ #
2
+ # Author:: Jay Vana <jsvana@fb.com>
3
+ # Author:: Davide Cavalca <dcavalca@fb.com>
4
+ # Copyright:: Copyright (c) 2016-2020 Facebook, 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
+
20
+ Ohai.plugin(:IPC) do
21
+ provides "ipc"
22
+ optional true
23
+
24
+ collect_data(:linux) do
25
+ ipcs_path = which("ipcs")
26
+ if ipcs_path
27
+ # NOTE: currently only supports shared memory
28
+ cmd = "#{ipcs_path} -m"
29
+ ipcs = shell_out(cmd)
30
+
31
+ ipc Mash.new unless ipc
32
+ ipc["shm"] = Mash.new unless ipc["shm"]
33
+
34
+ ipcs.stdout.split("\n").each do |line|
35
+ next unless line.start_with?("0x")
36
+
37
+ parts = line.split
38
+ segment = {
39
+ "key" => parts[0],
40
+ "owner" => parts[2],
41
+ "perms" => parts[3],
42
+ "bytes" => parts[4].to_i,
43
+ "nattch" => parts[5].to_i,
44
+ "status" => parts[6] ? parts[6] : "",
45
+ }
46
+
47
+ ipc["shm"][parts[1].to_i] = segment
48
+ end
49
+ end
50
+ end
51
+ end
@@ -207,6 +207,93 @@ Ohai.plugin(:Network) do
207
207
  iface
208
208
  end
209
209
 
210
+ # determine channel parameters for the interface using ethtool
211
+ def ethernet_channel_parameters(iface)
212
+ return iface unless ethtool_binary_path
213
+
214
+ iface.each_key do |tmp_int|
215
+ next unless iface[tmp_int][:encapsulation] == "Ethernet"
216
+
217
+ so = shell_out("#{ethtool_binary_path} -l #{tmp_int}")
218
+ logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
219
+ type = nil
220
+ iface[tmp_int]["channel_params"] = {}
221
+ so.stdout.lines.each do |line|
222
+ next if line.start_with?("Channel parameters for")
223
+ next if line.strip.nil?
224
+
225
+ if line =~ /Pre-set maximums/
226
+ type = "max"
227
+ next
228
+ end
229
+ if line =~ /Current hardware settings/
230
+ type = "current"
231
+ next
232
+ end
233
+ key, val = line.split(/:\s+/)
234
+ if type && val
235
+ channel_key = "#{type}_#{key.downcase.tr(" ", "_")}"
236
+ iface[tmp_int]["channel_params"][channel_key] = val.to_i
237
+ end
238
+ end
239
+ end
240
+ iface
241
+ end
242
+
243
+ # determine coalesce parameters for the interface using ethtool
244
+ def ethernet_coalesce_parameters(iface)
245
+ return iface unless ethtool_binary_path
246
+
247
+ iface.each_key do |tmp_int|
248
+ next unless iface[tmp_int][:encapsulation] == "Ethernet"
249
+
250
+ so = shell_out("#{ethtool_binary_path} -c #{tmp_int}")
251
+ logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
252
+ iface[tmp_int]["coalesce_params"] = {}
253
+ so.stdout.lines.each do |line|
254
+ next if line.start_with?("Coalesce parameters for")
255
+ next if line.strip.nil?
256
+
257
+ if line.start_with?("Adaptive")
258
+ _, adaptive_rx, _, adaptive_tx = line.split(/:\s+|\s+TX|\n/)
259
+ iface[tmp_int]["coalesce_params"]["adaptive_rx"] = adaptive_rx
260
+ iface[tmp_int]["coalesce_params"]["adaptive_tx"] = adaptive_tx
261
+ next
262
+ end
263
+ key, val = line.split(/:\s+/)
264
+ if val
265
+ coalesce_key = "#{key.downcase.tr(" ", "_")}"
266
+ iface[tmp_int]["coalesce_params"][coalesce_key] = val.to_i
267
+ end
268
+ end
269
+ end
270
+ iface
271
+ end
272
+
273
+ # determine driver info for the interface using ethtool
274
+ def ethernet_driver_info(iface)
275
+ return iface unless ethtool_binary_path
276
+
277
+ iface.each_key do |tmp_int|
278
+ next unless iface[tmp_int][:encapsulation] == "Ethernet"
279
+
280
+ so = shell_out("#{ethtool_binary_path} -i #{tmp_int}")
281
+ logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
282
+ iface[tmp_int]["driver_info"] = {}
283
+ so.stdout.lines.each do |line|
284
+ next if line.strip.nil?
285
+
286
+ key, val = line.split(/:\s+/)
287
+ if val.nil?
288
+ val = ""
289
+ end
290
+ driver_key = "#{key.downcase.tr(" ", "_")}"
291
+ iface[tmp_int]["driver_info"][driver_key] = val.chomp
292
+ end
293
+ end
294
+ iface
295
+ end
296
+
210
297
  # determine link stats, vlans, queue length, and state for an interface using ip
211
298
  def link_statistics(iface, net_counters)
212
299
  so = shell_out("ip -d -s link")
@@ -669,6 +756,9 @@ Ohai.plugin(:Network) do
669
756
 
670
757
  iface = ethernet_layer_one(iface)
671
758
  iface = ethernet_ring_parameters(iface)
759
+ iface = ethernet_channel_parameters(iface)
760
+ iface = ethernet_coalesce_parameters(iface)
761
+ iface = ethernet_driver_info(iface)
672
762
  counters[:network][:interfaces] = net_counters
673
763
  network["interfaces"] = iface
674
764
  end
@@ -191,7 +191,7 @@ Ohai.plugin(:Packages) do
191
191
  chunked_lines = so.stdout.lines.map(&:strip).chunk do |line|
192
192
  !line.empty? || nil
193
193
  end
194
- chunked_lines.each do |_, lines| # rubocop: disable Performance/HashEachMethods
194
+ chunked_lines.each do |_, lines| # rubocop: disable Style/HashEachMethods
195
195
  package = {}
196
196
  lines.each do |line|
197
197
  key, value = line.split(":", 2)
@@ -54,7 +54,7 @@ Ohai.plugin(:Rackspace) do
54
54
  wmi = WmiLite::Wmi.new
55
55
  if wmi.first_of("Win32_ComputerSystem")["PrimaryOwnerName"] == "Rackspace"
56
56
  logger.trace("Plugin Rackspace: has_rackspace_manufacturer? == true")
57
- return true
57
+ true
58
58
  end
59
59
  end
60
60
 
@@ -0,0 +1,94 @@
1
+ #
2
+ # Author:: Pete Higgins (pete@peterhiggins.org)
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ Ohai.plugin(:DMI) do
20
+ provides "dmi"
21
+
22
+ # Map the linux component types to their rough Windows API equivalents
23
+ DMI_TO_WIN32OLE ||= {
24
+ chassis: "SystemEnclosure",
25
+ processor: "Processor",
26
+ bios: "Bios",
27
+ system: "ComputerSystemProduct",
28
+ base_board: "BaseBoard",
29
+ }.freeze
30
+
31
+ # This regex is in 3 parts for the different supported patterns in camel
32
+ # case names coming from the Windows API:
33
+ # * Typical camelcase, eg Depth, PartNumber, NumberOfPowerCords
34
+ # * Acronyms preceding camelcase, eg SMBIOSAssetTag
35
+ # * Acronyms that occur at the end of the name, eg SKU, DeviceID
36
+ #
37
+ # This cannot handle some property names, eg SMBIOSBIOSVersion.
38
+ # https://rubular.com/r/FBNtXod4wkZGAG
39
+ SPLIT_REGEX ||= /[A-Z][a-z0-9]+|[A-Z]{2,}(?=[A-Z][a-z0-9])|[A-Z]{2,}/.freeze
40
+
41
+ WINDOWS_TO_UNIX_KEYS ||= [
42
+ %w{vendor manufacturer},
43
+ %w{identifying_number serial_number},
44
+ %w{name family},
45
+ ].freeze
46
+
47
+ collect_data(:windows) do
48
+ require "ohai/common/dmi"
49
+ require "wmi-lite/wmi"
50
+ wmi = WmiLite::Wmi.new
51
+
52
+ dmi Mash.new
53
+
54
+ # The Windows API returns property names in camel case, eg "SerialNumber",
55
+ # while `dmi` returns them as space separated strings, eg "Serial Number".
56
+ # `Ohai::Common::DMI.convenience_keys` expects property names in `dmi`'s
57
+ # format, so build two parallel hashes with the keys as they come from the
58
+ # Windows API and in a faked-out `dmi` version. After the call to
59
+ # `Ohai::Common::DMI.convenience_keys` replace the faked-out `dmi`
60
+ # collection with the one with the original property names.
61
+ DMI_TO_WIN32OLE.each do |dmi_key, ole_key|
62
+ wmi_objects = wmi.instances_of("Win32_#{ole_key}").map(&:wmi_ole_object)
63
+
64
+ split_name_properties = []
65
+ properties = []
66
+
67
+ wmi_objects.each do |wmi_object|
68
+ split_name_properties << Mash.new
69
+ properties << Mash.new
70
+
71
+ wmi_object.properties_.each do |property|
72
+ property_name = property.name
73
+ value = wmi_object.invoke(property_name)
74
+
75
+ split_name = property_name.scan(SPLIT_REGEX).join(" ")
76
+ split_name_properties.last[split_name] = value
77
+ properties.last[property_name] = value
78
+ end
79
+ end
80
+
81
+ dmi[dmi_key] = Mash.new(all_records: split_name_properties, _all_records: properties)
82
+ end
83
+
84
+ Ohai::Common::DMI.convenience_keys(dmi)
85
+
86
+ dmi.each_value do |records|
87
+ records[:all_records] = records.delete(:_all_records)
88
+
89
+ WINDOWS_TO_UNIX_KEYS.each do |windows_key, unix_key|
90
+ records[unix_key] = records.delete(windows_key) if records.key?(windows_key)
91
+ end
92
+ end
93
+ end
94
+ end
@@ -18,13 +18,11 @@
18
18
 
19
19
  Ohai.plugin :SystemEnclosure do
20
20
  provides "system_enclosure"
21
+ depends "dmi"
21
22
 
22
23
  collect_data(:windows) do
23
- require "wmi-lite/wmi"
24
24
  system_enclosure Mash.new
25
- wmi = WmiLite::Wmi.new
26
- wmi_object = wmi.first_of("Win32_SystemEnclosure").wmi_ole_object
27
- system_enclosure[:manufacturer] = wmi_object.invoke("manufacturer")
28
- system_enclosure[:serialnumber] = wmi_object.invoke("serialnumber")
25
+ system_enclosure[:manufacturer] = get_attribute(:dmi, :chassis, :manufacturer)
26
+ system_enclosure[:serialnumber] = get_attribute(:dmi, :chassis, :serial_number)
29
27
  end
30
28
  end
@@ -18,5 +18,5 @@
18
18
 
19
19
  module Ohai
20
20
  OHAI_ROOT = File.expand_path(File.dirname(__FILE__))
21
- VERSION = "15.12.0".freeze
21
+ VERSION = "16.0.20".freeze
22
22
  end
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_dependency "ipaddress"
25
25
  s.add_dependency "wmi-lite", "~> 1.0"
26
26
  s.add_dependency "ffi", "~> 1.9"
27
- s.add_dependency "chef-config", ">= 12.8", "< 16"
27
+ s.add_dependency "chef-config", ">= 12.8", "< 17"
28
28
  # Note for ohai developers: If chef-config causes you grief, try:
29
29
  # bundle install --with development
30
30
  # this should work as long as chef is a development dependency in Gemfile.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ohai
3
3
  version: !ruby/object:Gem::Version
4
- version: 15.12.0
4
+ version: 16.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Jacob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-23 00:00:00.000000000 Z
11
+ date: 2020-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: systemu
@@ -177,7 +177,7 @@ dependencies:
177
177
  version: '12.8'
178
178
  - - "<"
179
179
  - !ruby/object:Gem::Version
180
- version: '16'
180
+ version: '17'
181
181
  type: :runtime
182
182
  prerelease: false
183
183
  version_requirements: !ruby/object:Gem::Requirement
@@ -187,7 +187,7 @@ dependencies:
187
187
  version: '12.8'
188
188
  - - "<"
189
189
  - !ruby/object:Gem::Version
190
- version: '16'
190
+ version: '17'
191
191
  description: Ohai profiles your system and emits JSON
192
192
  email: adam@chef.io
193
193
  executables:
@@ -254,6 +254,7 @@ files:
254
254
  - lib/ohai/plugins/erlang.rb
255
255
  - lib/ohai/plugins/eucalyptus.rb
256
256
  - lib/ohai/plugins/filesystem.rb
257
+ - lib/ohai/plugins/fips.rb
257
258
  - lib/ohai/plugins/freebsd/memory.rb
258
259
  - lib/ohai/plugins/freebsd/network.rb
259
260
  - lib/ohai/plugins/freebsd/platform.rb
@@ -271,8 +272,9 @@ files:
271
272
  - lib/ohai/plugins/libvirt.rb
272
273
  - lib/ohai/plugins/linode.rb
273
274
  - lib/ohai/plugins/linux/block_device.rb
274
- - lib/ohai/plugins/linux/fips.rb
275
275
  - lib/ohai/plugins/linux/hostnamectl.rb
276
+ - lib/ohai/plugins/linux/interrupts.rb
277
+ - lib/ohai/plugins/linux/ipc.rb
276
278
  - lib/ohai/plugins/linux/lsb.rb
277
279
  - lib/ohai/plugins/linux/lspci.rb
278
280
  - lib/ohai/plugins/linux/machineid.rb
@@ -327,8 +329,8 @@ files:
327
329
  - lib/ohai/plugins/uptime.rb
328
330
  - lib/ohai/plugins/virtualbox.rb
329
331
  - lib/ohai/plugins/vmware.rb
332
+ - lib/ohai/plugins/windows/dmi.rb
330
333
  - lib/ohai/plugins/windows/drivers.rb
331
- - lib/ohai/plugins/windows/fips.rb
332
334
  - lib/ohai/plugins/windows/memory.rb
333
335
  - lib/ohai/plugins/windows/network.rb
334
336
  - lib/ohai/plugins/windows/platform.rb
@@ -1,38 +0,0 @@
1
- #
2
- # Author:: Matt Wrock (<matt@mattwrock.com>)
3
- # Copyright:: Copyright (c) 2016-2018 Chef Software, Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- # After long discussion in IRC the "powers that be" have come to a concensus
20
- # that there is no other Windows platforms exist that were not based on the
21
- # Windows_NT kernel, so we herby decree that "windows" will refer to all
22
- # platforms built upon the Windows_NT kernel and have access to win32 or win64
23
- # subsystems.
24
-
25
- Ohai.plugin(:Fips) do
26
- provides "fips"
27
-
28
- collect_data(:windows) do
29
- fips Mash.new
30
-
31
- require "openssl" unless defined?(OpenSSL)
32
- if defined?(OpenSSL.fips_mode) && OpenSSL.fips_mode && !$FIPS_TEST_MODE
33
- fips["kernel"] = { "enabled" => true }
34
- else
35
- fips["kernel"] = { "enabled" => false }
36
- end
37
- end
38
- end