ohai 15.12.0 → 16.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -5
- data/lib/ohai/common/dmi.rb +13 -5
- data/lib/ohai/mash.rb +21 -201
- data/lib/ohai/mixin/azure_metadata.rb +70 -14
- data/lib/ohai/mixin/ec2_metadata.rb +1 -1
- data/lib/ohai/mixin/gce_metadata.rb +2 -2
- data/lib/ohai/plugins/aix/uptime.rb +1 -1
- data/lib/ohai/plugins/c.rb +2 -2
- data/lib/ohai/plugins/cpu.rb +1 -1
- data/lib/ohai/plugins/docker.rb +1 -1
- data/lib/ohai/plugins/ec2.rb +1 -1
- data/lib/ohai/plugins/eucalyptus.rb +2 -2
- data/lib/ohai/plugins/filesystem.rb +9 -43
- data/lib/ohai/plugins/{linux/fips.rb → fips.rb} +1 -1
- data/lib/ohai/plugins/gce.rb +1 -1
- data/lib/ohai/plugins/linux/interrupts.rb +83 -0
- data/lib/ohai/plugins/linux/ipc.rb +51 -0
- data/lib/ohai/plugins/linux/mdadm.rb +1 -1
- data/lib/ohai/plugins/linux/network.rb +92 -0
- data/lib/ohai/plugins/linux/selinux.rb +68 -0
- data/lib/ohai/plugins/linux/virtualization.rb +5 -2
- data/lib/ohai/plugins/packages.rb +1 -1
- data/lib/ohai/plugins/rackspace.rb +1 -1
- data/lib/ohai/plugins/virtualbox.rb +2 -2
- data/lib/ohai/plugins/windows/dmi.rb +94 -0
- data/lib/ohai/plugins/windows/system_enclosure.rb +3 -5
- data/lib/ohai/version.rb +1 -1
- data/ohai.gemspec +2 -1
- metadata +29 -6
- data/lib/ohai/plugins/windows/fips.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: caa70e908138b3a05e5936f250179ad6eb43720978cc1c4296011df3d9da7478
|
4
|
+
data.tar.gz: 91020ca991c49f7e029604403bf4421be6f608fc5330bf787eae09b3dd6cb844
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4204d5dadf0987967638c08e61124c5226810a07c83b200a4b7713c4736ce97f9bf229210fa19c06ab09d8aa4363b0389192598710d75d1b92ab055c473401d
|
7
|
+
data.tar.gz: 3f1620eb9f6fc44f2fc3f81e974be7d69762d7a783a010b30b415fd6365db4584daa57e42d985055551aeac94bf540986f6a6e5419b22a2ea4118fc1a0a0b03b
|
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", "
|
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"
|
data/lib/ohai/common/dmi.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
data/lib/ohai/mash.rb
CHANGED
@@ -1,201 +1,21 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
11
|
-
#
|
12
|
-
#
|
13
|
-
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
#
|
21
|
-
|
22
|
-
# ---
|
23
|
-
# ---
|
24
|
-
|
25
|
-
# Some portions of blank.rb and mash.rb are verbatim copies of software
|
26
|
-
# licensed under the MIT license. That license is included below:
|
27
|
-
|
28
|
-
# Copyright (c) 2005-2008 David Heinemeier Hansson
|
29
|
-
|
30
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
31
|
-
# a copy of this software and associated documentation files (the
|
32
|
-
# "Software"), to deal in the Software without restriction, including
|
33
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
34
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
35
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
36
|
-
# the following conditions:
|
37
|
-
|
38
|
-
# The above copyright notice and this permission notice shall be
|
39
|
-
# included in all copies or substantial portions of the Software.
|
40
|
-
|
41
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
42
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
43
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
44
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
45
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
46
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
47
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
48
|
-
|
49
|
-
# This class has dubious semantics and we only have it so that people can write
|
50
|
-
# params[:key] instead of params['key'].
|
51
|
-
class Mash < Hash
|
52
|
-
|
53
|
-
# @param constructor [Object] The default value for the mash.
|
54
|
-
# If constructor is a Hash, a new mash will be created based on the keys of the hash and
|
55
|
-
# no default value will be set.
|
56
|
-
def initialize(constructor = {})
|
57
|
-
if constructor.is_a?(Hash)
|
58
|
-
super()
|
59
|
-
update(constructor)
|
60
|
-
else
|
61
|
-
super(constructor)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# @param key [Object] The default value for the mash.
|
66
|
-
# If key is a Symbol and it is a key in the mash, then the default value will be set to
|
67
|
-
# the value matching the key.
|
68
|
-
def default(key = nil)
|
69
|
-
if key.is_a?(Symbol) && include?(key = key.to_s)
|
70
|
-
self[key]
|
71
|
-
else
|
72
|
-
super
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
77
|
-
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
78
|
-
|
79
|
-
# @param key [Object] The key to set.
|
80
|
-
# @param value [Object] The value to set the key to.
|
81
|
-
#
|
82
|
-
# @see Mash#convert_key
|
83
|
-
# @see Mash#convert_value
|
84
|
-
def []=(key, value)
|
85
|
-
regular_writer(convert_key(key), convert_value(value))
|
86
|
-
end
|
87
|
-
|
88
|
-
# @param other_hash [Hash]
|
89
|
-
# A hash to update values in the mash with. The keys and the values will be
|
90
|
-
# converted to Mash format.
|
91
|
-
#
|
92
|
-
# @return [Mash] The updated mash.
|
93
|
-
def update(other_hash)
|
94
|
-
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
95
|
-
self
|
96
|
-
end
|
97
|
-
|
98
|
-
alias_method :merge!, :update
|
99
|
-
|
100
|
-
# @param key [Object] The key to check for. This will be run through convert_key.
|
101
|
-
#
|
102
|
-
# @return [Boolean] True if the key exists in the mash.
|
103
|
-
def key?(key)
|
104
|
-
super(convert_key(key))
|
105
|
-
end
|
106
|
-
|
107
|
-
# def include? def has_key? def member?
|
108
|
-
alias_method :include?, :key?
|
109
|
-
alias_method :has_key?, :key?
|
110
|
-
alias_method :member?, :key?
|
111
|
-
|
112
|
-
# @param key [Object] The key to fetch. This will be run through convert_key.
|
113
|
-
# @param extras [Array] Default value.
|
114
|
-
#
|
115
|
-
# @return [Object] The value at key or the default value.
|
116
|
-
def fetch(key, *extras)
|
117
|
-
super(convert_key(key), *extras)
|
118
|
-
end
|
119
|
-
|
120
|
-
# @param indices [Array] The keys to retrieve values for. These will be run through +convert_key+.
|
121
|
-
#
|
122
|
-
# @return [Array] The values at each of the provided keys
|
123
|
-
def values_at(*indices)
|
124
|
-
indices.collect { |key| self[convert_key(key)] }
|
125
|
-
end
|
126
|
-
|
127
|
-
# @param hash [Hash] The hash to merge with the mash.
|
128
|
-
#
|
129
|
-
# @return [Mash] A new mash with the hash values merged in.
|
130
|
-
def merge(hash)
|
131
|
-
dup.update(hash)
|
132
|
-
end
|
133
|
-
|
134
|
-
# @param key [Object] The key to delete from the mash.
|
135
|
-
def delete(key)
|
136
|
-
super(convert_key(key))
|
137
|
-
end
|
138
|
-
|
139
|
-
# @param keys [Array<String, Symbol>] The mash keys to exclude.
|
140
|
-
#
|
141
|
-
# @return [Mash] A new mash without the selected keys.
|
142
|
-
#
|
143
|
-
# @example
|
144
|
-
# { :one => 1, :two => 2, :three => 3 }.except(:one)
|
145
|
-
# #=> { "two" => 2, "three" => 3 }
|
146
|
-
def except(*keys)
|
147
|
-
super(*keys.map { |k| convert_key(k) })
|
148
|
-
end
|
149
|
-
|
150
|
-
# Used to provide the same interface as Hash.
|
151
|
-
#
|
152
|
-
# @return [Mash] This mash unchanged.
|
153
|
-
def stringify_keys!; self end
|
154
|
-
|
155
|
-
# @return [Hash] The mash as a Hash with symbolized keys.
|
156
|
-
def symbolize_keys
|
157
|
-
h = Hash.new(default)
|
158
|
-
each { |key, val| h[key.to_sym] = val }
|
159
|
-
h
|
160
|
-
end
|
161
|
-
|
162
|
-
# @return [Hash] The mash as a Hash with string keys.
|
163
|
-
def to_hash
|
164
|
-
Hash.new(default).merge(self)
|
165
|
-
end
|
166
|
-
|
167
|
-
# Convert a Hash into a Mash. The input Hash's default value is maintained
|
168
|
-
# @return [Mash]
|
169
|
-
def self.from_hash(hash)
|
170
|
-
mash = Mash.new(hash)
|
171
|
-
mash.default = hash.default
|
172
|
-
mash
|
173
|
-
end
|
174
|
-
|
175
|
-
protected
|
176
|
-
|
177
|
-
# @param key [Object] The key to convert.
|
178
|
-
# @return [Object] The converted key. If the key was a symbol, it will be converted to a string.
|
179
|
-
#
|
180
|
-
# @api private
|
181
|
-
def convert_key(key)
|
182
|
-
key.is_a?(Symbol) ? key.to_s : key
|
183
|
-
end
|
184
|
-
|
185
|
-
# @param value [Object] The value to convert.
|
186
|
-
#
|
187
|
-
# @return [Object]
|
188
|
-
# The converted value. A Hash or an Array of hashes, will be converted to
|
189
|
-
# their Mash equivalents.
|
190
|
-
#
|
191
|
-
# @api private
|
192
|
-
def convert_value(value)
|
193
|
-
if value.class == Hash
|
194
|
-
Mash.from_hash(value)
|
195
|
-
elsif value.is_a?(Array)
|
196
|
-
value.collect { |e| convert_value(e) }
|
197
|
-
else
|
198
|
-
value
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require "chef-utils/mash" unless defined?(ChefUtils::Mash)
|
19
|
+
|
20
|
+
# For historical reasons we inject Mash directly into the top level class namespace
|
21
|
+
Mash = ChefUtils::Mash unless defined?(Mash)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
# Author:: Tim Smith (<tsmith@chef.io>)
|
3
|
-
# Copyright::
|
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
|
-
#
|
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
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
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 =
|
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 =
|
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 =
|
60
|
+
data = String(data)
|
61
61
|
parser = FFI_Yajl::Parser.new
|
62
62
|
begin
|
63
63
|
parser.parse(data)
|
@@ -30,7 +30,7 @@ Ohai.plugin(:Uptime) do
|
|
30
30
|
so = shell_out("LC_ALL=POSIX ps -o etime= -p 1").stdout.strip
|
31
31
|
|
32
32
|
# Here we'll check our shell_out for a dash, which indicates there is a # of days involved
|
33
|
-
# We'll chunk off the days, hours (where applicable), minutes, seconds into
|
33
|
+
# We'll chunk off the days, hours (where applicable), minutes, seconds into separate vars
|
34
34
|
# We also need to do this because ps -o etime= will not display days if the machine has been up for less than 24 hours
|
35
35
|
# If the machine has been up for less than one hour, the shell_out will not output hours hence our else
|
36
36
|
# see here: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.cmds4/ps.htm#ps__row-d3e109655
|
data/lib/ohai/plugins/c.rb
CHANGED
@@ -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
|
-
|
39
|
+
true
|
40
40
|
else
|
41
41
|
logger.trace("Plugin C: Xcode Command Line Tools not found.")
|
42
|
-
|
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.")
|
data/lib/ohai/plugins/cpu.rb
CHANGED
@@ -364,7 +364,7 @@ Ohai.plugin(:CPU) do
|
|
364
364
|
cpu["cpustates"][value] += 1
|
365
365
|
when /core_id/
|
366
366
|
cpu[instance]["core_id"] = value
|
367
|
-
|
367
|
+
# Detect hyperthreading/multithreading
|
368
368
|
cpucores.push(value) if cpucores.index(value).nil?
|
369
369
|
when /family|fpu_type|model|stepping|vendor_id/
|
370
370
|
cpu[instance][key] = value
|
data/lib/ohai/plugins/docker.rb
CHANGED
@@ -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
|
-
|
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')
|
data/lib/ohai/plugins/ec2.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
35
|
+
detected_addresses.first
|
36
36
|
else
|
37
|
-
|
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-
|
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
|
-
#
|
500
|
-
|
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
|
-
#
|
656
|
-
|
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
|
-
#
|
749
|
-
|
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
|
|
data/lib/ohai/plugins/gce.rb
CHANGED
@@ -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
|
-
|
57
|
+
true
|
58
58
|
end
|
59
59
|
else
|
60
60
|
logger.trace("Plugin GCE: has_gce_system_info? == false")
|
@@ -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
|
@@ -105,7 +105,7 @@ Ohai.plugin(:Mdadm) do
|
|
105
105
|
# gather detailed information on the array
|
106
106
|
so = shell_out("mdadm --detail /dev/#{device}")
|
107
107
|
|
108
|
-
# if the mdadm command was
|
108
|
+
# if the mdadm command was successful pass so.stdout to create_raid_device_mash to grab the tidbits we want
|
109
109
|
mdadm[device] = create_raid_device_mash(so.stdout) if so.stdout
|
110
110
|
mdadm[device]["members"] = devices[device]["active"]
|
111
111
|
mdadm[device]["spares"] = devices[device]["spare"]
|
@@ -108,6 +108,8 @@ Ohai.plugin(:Network) do
|
|
108
108
|
# http://rubular.com/r/pwTNp65VFf
|
109
109
|
route_entry[k] = $1 if route_ending =~ /\b#{k}\s+([^\s]+)/
|
110
110
|
end
|
111
|
+
# https://rubular.com/r/k1sMrRn5yLjgVi
|
112
|
+
route_entry["via"] = $1 if route_ending =~ /\bvia\s+inet6\s+([^\s]+)/
|
111
113
|
|
112
114
|
# a sanity check, especially for Linux-VServer, OpenVZ and LXC:
|
113
115
|
# don't report the route entry if the src address isn't set on the node
|
@@ -207,6 +209,93 @@ Ohai.plugin(:Network) do
|
|
207
209
|
iface
|
208
210
|
end
|
209
211
|
|
212
|
+
# determine channel parameters for the interface using ethtool
|
213
|
+
def ethernet_channel_parameters(iface)
|
214
|
+
return iface unless ethtool_binary_path
|
215
|
+
|
216
|
+
iface.each_key do |tmp_int|
|
217
|
+
next unless iface[tmp_int][:encapsulation] == "Ethernet"
|
218
|
+
|
219
|
+
so = shell_out("#{ethtool_binary_path} -l #{tmp_int}")
|
220
|
+
logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
|
221
|
+
type = nil
|
222
|
+
iface[tmp_int]["channel_params"] = {}
|
223
|
+
so.stdout.lines.each do |line|
|
224
|
+
next if line.start_with?("Channel parameters for")
|
225
|
+
next if line.strip.nil?
|
226
|
+
|
227
|
+
if line =~ /Pre-set maximums/
|
228
|
+
type = "max"
|
229
|
+
next
|
230
|
+
end
|
231
|
+
if line =~ /Current hardware settings/
|
232
|
+
type = "current"
|
233
|
+
next
|
234
|
+
end
|
235
|
+
key, val = line.split(/:\s+/)
|
236
|
+
if type && val
|
237
|
+
channel_key = "#{type}_#{key.downcase.tr(" ", "_")}"
|
238
|
+
iface[tmp_int]["channel_params"][channel_key] = val.to_i
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
iface
|
243
|
+
end
|
244
|
+
|
245
|
+
# determine coalesce parameters for the interface using ethtool
|
246
|
+
def ethernet_coalesce_parameters(iface)
|
247
|
+
return iface unless ethtool_binary_path
|
248
|
+
|
249
|
+
iface.each_key do |tmp_int|
|
250
|
+
next unless iface[tmp_int][:encapsulation] == "Ethernet"
|
251
|
+
|
252
|
+
so = shell_out("#{ethtool_binary_path} -c #{tmp_int}")
|
253
|
+
logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
|
254
|
+
iface[tmp_int]["coalesce_params"] = {}
|
255
|
+
so.stdout.lines.each do |line|
|
256
|
+
next if line.start_with?("Coalesce parameters for")
|
257
|
+
next if line.strip.nil?
|
258
|
+
|
259
|
+
if line.start_with?("Adaptive")
|
260
|
+
_, adaptive_rx, _, adaptive_tx = line.split(/:\s+|\s+TX|\n/)
|
261
|
+
iface[tmp_int]["coalesce_params"]["adaptive_rx"] = adaptive_rx
|
262
|
+
iface[tmp_int]["coalesce_params"]["adaptive_tx"] = adaptive_tx
|
263
|
+
next
|
264
|
+
end
|
265
|
+
key, val = line.split(/:\s+/)
|
266
|
+
if val
|
267
|
+
coalesce_key = "#{key.downcase.tr(" ", "_")}"
|
268
|
+
iface[tmp_int]["coalesce_params"][coalesce_key] = val.to_i
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
iface
|
273
|
+
end
|
274
|
+
|
275
|
+
# determine driver info for the interface using ethtool
|
276
|
+
def ethernet_driver_info(iface)
|
277
|
+
return iface unless ethtool_binary_path
|
278
|
+
|
279
|
+
iface.each_key do |tmp_int|
|
280
|
+
next unless iface[tmp_int][:encapsulation] == "Ethernet"
|
281
|
+
|
282
|
+
so = shell_out("#{ethtool_binary_path} -i #{tmp_int}")
|
283
|
+
logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
|
284
|
+
iface[tmp_int]["driver_info"] = {}
|
285
|
+
so.stdout.lines.each do |line|
|
286
|
+
next if line.strip.nil?
|
287
|
+
|
288
|
+
key, val = line.split(/:\s+/)
|
289
|
+
if val.nil?
|
290
|
+
val = ""
|
291
|
+
end
|
292
|
+
driver_key = "#{key.downcase.tr(" ", "_")}"
|
293
|
+
iface[tmp_int]["driver_info"][driver_key] = val.chomp
|
294
|
+
end
|
295
|
+
end
|
296
|
+
iface
|
297
|
+
end
|
298
|
+
|
210
299
|
# determine link stats, vlans, queue length, and state for an interface using ip
|
211
300
|
def link_statistics(iface, net_counters)
|
212
301
|
so = shell_out("ip -d -s link")
|
@@ -669,6 +758,9 @@ Ohai.plugin(:Network) do
|
|
669
758
|
|
670
759
|
iface = ethernet_layer_one(iface)
|
671
760
|
iface = ethernet_ring_parameters(iface)
|
761
|
+
iface = ethernet_channel_parameters(iface)
|
762
|
+
iface = ethernet_coalesce_parameters(iface)
|
763
|
+
iface = ethernet_driver_info(iface)
|
672
764
|
counters[:network][:interfaces] = net_counters
|
673
765
|
network["interfaces"] = iface
|
674
766
|
end
|
@@ -0,0 +1,68 @@
|
|
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(:Selinux) do
|
20
|
+
provides "selinux/status", "selinux/policy_booleans", "selinux/process_contexts", "selinux/file_contexts"
|
21
|
+
optional true
|
22
|
+
|
23
|
+
collect_data(:linux) do
|
24
|
+
sestatus_path = which("sestatus")
|
25
|
+
if sestatus_path
|
26
|
+
sestatus = shell_out("#{sestatus_path} -v -b")
|
27
|
+
|
28
|
+
selinux Mash.new unless selinux
|
29
|
+
selinux[:status] ||= Mash.new
|
30
|
+
selinux[:policy_booleans] ||= Mash.new
|
31
|
+
selinux[:process_contexts] ||= Mash.new
|
32
|
+
selinux[:file_contexts] ||= Mash.new
|
33
|
+
section = nil
|
34
|
+
|
35
|
+
sestatus.stdout.split("\n").each do |line|
|
36
|
+
line.chomp!
|
37
|
+
|
38
|
+
case line
|
39
|
+
when "Policy booleans:"
|
40
|
+
section = :policy_booleans
|
41
|
+
next
|
42
|
+
when "Process contexts:"
|
43
|
+
section = :process_contexts
|
44
|
+
next
|
45
|
+
when "File contexts:"
|
46
|
+
section = :file_contexts
|
47
|
+
next
|
48
|
+
else
|
49
|
+
if section.nil?
|
50
|
+
section = :status
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
key, val = line.split(/:?\s\s+/, 2)
|
55
|
+
next if key.nil?
|
56
|
+
|
57
|
+
unless key.start_with?("/")
|
58
|
+
key.downcase!
|
59
|
+
key.tr!(" ", "_")
|
60
|
+
end
|
61
|
+
|
62
|
+
selinux[section][key] = val
|
63
|
+
end
|
64
|
+
else
|
65
|
+
logger.debug("Plugin Selinux: Could not find sestatus. Skipping plugin.")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -190,8 +190,11 @@ Ohai.plugin(:Virtualization) do
|
|
190
190
|
# Kernel docs, https://www.kernel.org/doc/Documentation/cgroups
|
191
191
|
if File.exist?("/proc/self/cgroup")
|
192
192
|
cgroup_content = File.read("/proc/self/cgroup")
|
193
|
-
|
194
|
-
|
193
|
+
# These two REs catch many different examples. Here's a specific one
|
194
|
+
# from when it is docker and there is no subsystem name.
|
195
|
+
# https://rubular.com/r/dV13hiU9KxmiWB
|
196
|
+
if cgroup_content =~ %r{^\d+:[^:]*:/(lxc|docker)/.+$} ||
|
197
|
+
cgroup_content =~ %r{^\d+:[^:]*:/[^/]+/(lxc|docker)-?.+$}
|
195
198
|
logger.trace("Plugin Virtualization: /proc/self/cgroup indicates #{$1} container. Detecting as #{$1} guest")
|
196
199
|
virtualization[:system] = $1
|
197
200
|
virtualization[:role] = "guest"
|
@@ -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
|
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)
|
@@ -93,8 +93,8 @@ Ohai.plugin(:Virtualbox) do
|
|
93
93
|
so_cmd = "VBoxManage list --sorted #{query_type}"
|
94
94
|
logger.trace(so_cmd)
|
95
95
|
so = shell_out(so_cmd)
|
96
|
-
|
97
|
-
|
96
|
+
# raise an exception if the command fails
|
97
|
+
# so.error!
|
98
98
|
|
99
99
|
if so.exitstatus == 0
|
100
100
|
# break the result into paragraph blocks, on successive newlines
|
@@ -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
|
-
|
26
|
-
|
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
|
data/lib/ohai/version.rb
CHANGED
data/ohai.gemspec
CHANGED
@@ -24,7 +24,8 @@ 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", "<
|
27
|
+
s.add_dependency "chef-config", ">= 12.8", "< 17"
|
28
|
+
s.add_dependency "chef-utils", ">= 16.0", "< 17"
|
28
29
|
# Note for ohai developers: If chef-config causes you grief, try:
|
29
30
|
# bundle install --with development
|
30
31
|
# 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:
|
4
|
+
version: 16.2.3
|
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-
|
11
|
+
date: 2020-06-30 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: '
|
180
|
+
version: '17'
|
181
181
|
type: :runtime
|
182
182
|
prerelease: false
|
183
183
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -187,7 +187,27 @@ dependencies:
|
|
187
187
|
version: '12.8'
|
188
188
|
- - "<"
|
189
189
|
- !ruby/object:Gem::Version
|
190
|
-
version: '
|
190
|
+
version: '17'
|
191
|
+
- !ruby/object:Gem::Dependency
|
192
|
+
name: chef-utils
|
193
|
+
requirement: !ruby/object:Gem::Requirement
|
194
|
+
requirements:
|
195
|
+
- - ">="
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '16.0'
|
198
|
+
- - "<"
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '17'
|
201
|
+
type: :runtime
|
202
|
+
prerelease: false
|
203
|
+
version_requirements: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - ">="
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '16.0'
|
208
|
+
- - "<"
|
209
|
+
- !ruby/object:Gem::Version
|
210
|
+
version: '17'
|
191
211
|
description: Ohai profiles your system and emits JSON
|
192
212
|
email: adam@chef.io
|
193
213
|
executables:
|
@@ -254,6 +274,7 @@ files:
|
|
254
274
|
- lib/ohai/plugins/erlang.rb
|
255
275
|
- lib/ohai/plugins/eucalyptus.rb
|
256
276
|
- lib/ohai/plugins/filesystem.rb
|
277
|
+
- lib/ohai/plugins/fips.rb
|
257
278
|
- lib/ohai/plugins/freebsd/memory.rb
|
258
279
|
- lib/ohai/plugins/freebsd/network.rb
|
259
280
|
- lib/ohai/plugins/freebsd/platform.rb
|
@@ -271,8 +292,9 @@ files:
|
|
271
292
|
- lib/ohai/plugins/libvirt.rb
|
272
293
|
- lib/ohai/plugins/linode.rb
|
273
294
|
- lib/ohai/plugins/linux/block_device.rb
|
274
|
-
- lib/ohai/plugins/linux/fips.rb
|
275
295
|
- lib/ohai/plugins/linux/hostnamectl.rb
|
296
|
+
- lib/ohai/plugins/linux/interrupts.rb
|
297
|
+
- lib/ohai/plugins/linux/ipc.rb
|
276
298
|
- lib/ohai/plugins/linux/lsb.rb
|
277
299
|
- lib/ohai/plugins/linux/lspci.rb
|
278
300
|
- lib/ohai/plugins/linux/machineid.rb
|
@@ -280,6 +302,7 @@ files:
|
|
280
302
|
- lib/ohai/plugins/linux/memory.rb
|
281
303
|
- lib/ohai/plugins/linux/network.rb
|
282
304
|
- lib/ohai/plugins/linux/platform.rb
|
305
|
+
- lib/ohai/plugins/linux/selinux.rb
|
283
306
|
- lib/ohai/plugins/linux/sessions.rb
|
284
307
|
- lib/ohai/plugins/linux/sysctl.rb
|
285
308
|
- lib/ohai/plugins/linux/systemd_paths.rb
|
@@ -327,8 +350,8 @@ files:
|
|
327
350
|
- lib/ohai/plugins/uptime.rb
|
328
351
|
- lib/ohai/plugins/virtualbox.rb
|
329
352
|
- lib/ohai/plugins/vmware.rb
|
353
|
+
- lib/ohai/plugins/windows/dmi.rb
|
330
354
|
- lib/ohai/plugins/windows/drivers.rb
|
331
|
-
- lib/ohai/plugins/windows/fips.rb
|
332
355
|
- lib/ohai/plugins/windows/memory.rb
|
333
356
|
- lib/ohai/plugins/windows/network.rb
|
334
357
|
- 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
|