genesis_collector 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +13 -0
- data/Rakefile +2 -0
- data/genesis_collector.gemspec +1 -3
- data/lib/genesis_collector/collector.rb +23 -4
- data/lib/genesis_collector/dmidecode.rb +41 -0
- data/lib/genesis_collector/network_interfaces.rb +16 -4
- data/lib/genesis_collector/version.rb +1 -1
- metadata +6 -21
- data/lib/core_ext/try.rb +0 -102
- data/lib/genesis_collector/lshw.rb +0 -11
- data/lib/genesis_collector/lshw_parser.rb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 208f4ec96b38ba5d57e06c70ec9cf0771b566da9
|
4
|
+
data.tar.gz: 08e9f2d38f9a0df9bbf83080dfb086b499c3cb5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 786aa2d00b95c9bd341adc132166346c1e764a25ea8051d0d9373b6b52e1a2898dbe83cef3fad4d8765045e48546a3e4d39ec9c66208f583fe7e0092cbb4fc49
|
7
|
+
data.tar.gz: 12c5f4036cf0908efaded80a491143ef29f9e15ed98d9d27b2520bb70ab02d0862300075220335f0640030d737b78c20e95ed62c282aef46d85521875bda0bd6
|
data/.travis.yml
ADDED
data/Rakefile
CHANGED
data/genesis_collector.gemspec
CHANGED
@@ -18,9 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.
|
22
|
-
|
23
|
-
spec.add_development_dependency 'bundler', '~> 1.11'
|
21
|
+
spec.add_development_dependency 'bundler'
|
24
22
|
spec.add_development_dependency 'rake', '~> 10.0'
|
25
23
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
24
|
spec.add_development_dependency 'webmock', '~> 1.22'
|
@@ -5,8 +5,8 @@ require 'genesis_collector/simple_http'
|
|
5
5
|
require 'genesis_collector/network_interfaces'
|
6
6
|
require 'genesis_collector/chef'
|
7
7
|
require 'genesis_collector/ipmi'
|
8
|
-
require 'genesis_collector/lshw'
|
9
8
|
require 'genesis_collector/disks'
|
9
|
+
require 'genesis_collector/dmidecode'
|
10
10
|
require 'English'
|
11
11
|
|
12
12
|
module GenesisCollector
|
@@ -16,8 +16,8 @@ module GenesisCollector
|
|
16
16
|
include GenesisCollector::NetworkInterfaces
|
17
17
|
include GenesisCollector::Chef
|
18
18
|
include GenesisCollector::IPMI
|
19
|
-
include GenesisCollector::Lshw
|
20
19
|
include GenesisCollector::Disks
|
20
|
+
include GenesisCollector::DmiDecode
|
21
21
|
|
22
22
|
def initialize(config = {})
|
23
23
|
@chef_node = config.delete(:chef_node)
|
@@ -71,11 +71,30 @@ module GenesisCollector
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def collect_cpus
|
74
|
-
@payload[:cpus] =
|
74
|
+
@payload[:cpus] = get_dmi_data['processor'].map do |p|
|
75
|
+
{
|
76
|
+
description: p['version'],
|
77
|
+
cores: p['core_count'].to_i,
|
78
|
+
threads: p['thread_count'].to_i,
|
79
|
+
speed: p['current_speed'],
|
80
|
+
vendor_name: p['manufacturer'],
|
81
|
+
physid: p['socket_designation']
|
82
|
+
}
|
83
|
+
end
|
75
84
|
end
|
76
85
|
|
77
86
|
def collect_memories
|
78
|
-
@payload[:memories] =
|
87
|
+
@payload[:memories] = get_dmi_data['memory'].map do |m|
|
88
|
+
empty = m['size'] == 'No Module Installed'
|
89
|
+
{
|
90
|
+
size: m['size'].to_i * 1000000,
|
91
|
+
description: empty ? "Empty #{m['form_factor']}" : "#{m['form_factor']} #{m['type_detail']} #{m['speed']}",
|
92
|
+
bank: m['bank_locator'],
|
93
|
+
slot: m['locator'],
|
94
|
+
product: empty ? nil : m['part_number'],
|
95
|
+
vendor_name: empty ? nil : m['manufacturer']
|
96
|
+
}
|
97
|
+
end
|
79
98
|
end
|
80
99
|
|
81
100
|
private
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module GenesisCollector
|
2
|
+
module DmiDecode
|
3
|
+
|
4
|
+
def get_dmi_data
|
5
|
+
@dmi_data ||= parse_dmidecode(shellout_with_timeout('dmidecode --type processor --type memory'))
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse_dmidecode(data)
|
9
|
+
dict={}
|
10
|
+
handle = 0
|
11
|
+
current_title = nil
|
12
|
+
|
13
|
+
data.lines.each do |line|
|
14
|
+
case line
|
15
|
+
when /^End Of Table/, /^\s+$/, /^\# dmidecode/, /^SMBIOS/, /structures occupying/, /^Table at/
|
16
|
+
next
|
17
|
+
when /^Handle\s+(.*?),\s+/
|
18
|
+
handle = $1.to_i(16)
|
19
|
+
when /(.*)\s+Information\n$/, /(.*)\s+Device\n$/, /(.*)\s+Device Mapped Address\n$/, /(.*)\s+Array Mapped Address\n$/
|
20
|
+
title = standardize_dmi_key($1)
|
21
|
+
current_title = title
|
22
|
+
dict[title] ||= []
|
23
|
+
dict[title] << {'handle' => handle}
|
24
|
+
else
|
25
|
+
raw_data = line.strip.split(':')
|
26
|
+
if raw_data.is_a?(Array) && raw_data.length == 2
|
27
|
+
k, v = raw_data
|
28
|
+
dict[current_title].last[standardize_dmi_key(k)] = v.strip
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
dict
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def standardize_dmi_key(k)
|
38
|
+
k.downcase.gsub(/\s+/,'_')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -17,17 +17,14 @@ module GenesisCollector
|
|
17
17
|
end
|
18
18
|
@payload[:network_interfaces] = interfaces.reduce([]) { |memo, (k, v)| memo << v.merge(name: k) }
|
19
19
|
@payload[:network_interfaces].each do |i|
|
20
|
-
lshw_interface = get_lshw_data.network_interfaces.select { |lshw_i| lshw_i[:name] == i[:name] }[0]
|
21
20
|
i[:status] = read_interface_info(i[:name], 'operstate')
|
22
21
|
i[:mac_address] = read_mac_address(i[:name])
|
23
|
-
i[:product] = lshw_interface.try(:[], :product)
|
24
22
|
if i[:status] == 'up'
|
25
23
|
i[:speed] = get_interface_speed(i[:name])
|
26
24
|
i[:duplex] = read_interface_info(i[:name], 'duplex')
|
27
25
|
end
|
28
|
-
i[:vendor_name] = lshw_interface.try(:[], :vendor_name)
|
29
|
-
i[:link_type] = lshw_interface.try(:[], :link_type)
|
30
26
|
i[:neighbor] = get_network_neighbor(i[:name])
|
27
|
+
i.merge!(get_lspci_data(i[:name])) unless i[:name].include?('bond')
|
31
28
|
i.merge!(get_interface_driver(i[:name]))
|
32
29
|
end
|
33
30
|
end
|
@@ -91,5 +88,20 @@ module GenesisCollector
|
|
91
88
|
data
|
92
89
|
end
|
93
90
|
|
91
|
+
def get_lspci_data(interface)
|
92
|
+
slot = File.basename(File.readlink("/sys/class/net/#{interface}/device"))
|
93
|
+
raw_data = shellout_with_timeout("lspci -v -mm -s #{slot}")
|
94
|
+
data = {}
|
95
|
+
raw_data.each_line do |line|
|
96
|
+
if line.match(/^Vendor:(.*)$/)
|
97
|
+
data[:vendor_name] = $1.strip
|
98
|
+
end
|
99
|
+
if line.match(/^Device:(.*)$/)
|
100
|
+
data[:product] = $1.strip
|
101
|
+
end
|
102
|
+
end
|
103
|
+
data
|
104
|
+
end
|
105
|
+
|
94
106
|
end
|
95
107
|
end
|
metadata
CHANGED
@@ -1,43 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: genesis_collector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Radcliffe
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
|
-
type: :
|
20
|
+
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.11'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.11'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,6 +76,7 @@ extra_rdoc_files: []
|
|
90
76
|
files:
|
91
77
|
- ".gitignore"
|
92
78
|
- ".rspec"
|
79
|
+
- ".travis.yml"
|
93
80
|
- Gemfile
|
94
81
|
- LICENSE.txt
|
95
82
|
- README.md
|
@@ -100,14 +87,12 @@ files:
|
|
100
87
|
- exe/genesis_collector
|
101
88
|
- genesis_collector.gemspec
|
102
89
|
- lib/chef/handler/genesis.rb
|
103
|
-
- lib/core_ext/try.rb
|
104
90
|
- lib/genesis_collector.rb
|
105
91
|
- lib/genesis_collector/chef.rb
|
106
92
|
- lib/genesis_collector/collector.rb
|
107
93
|
- lib/genesis_collector/disks.rb
|
94
|
+
- lib/genesis_collector/dmidecode.rb
|
108
95
|
- lib/genesis_collector/ipmi.rb
|
109
|
-
- lib/genesis_collector/lshw.rb
|
110
|
-
- lib/genesis_collector/lshw_parser.rb
|
111
96
|
- lib/genesis_collector/network_interfaces.rb
|
112
97
|
- lib/genesis_collector/simple_http.rb
|
113
98
|
- lib/genesis_collector/version.rb
|
data/lib/core_ext/try.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
# https://github.com/rails/rails/blob/ff7d37d5884be3939833fb52b58a95017369eda5/activesupport/lib/active_support/core_ext/object/try.rb
|
2
|
-
|
3
|
-
class Object
|
4
|
-
# Invokes the public method whose name goes as first argument just like
|
5
|
-
# +public_send+ does, except that if the receiver does not respond to it the
|
6
|
-
# call returns +nil+ rather than raising an exception.
|
7
|
-
#
|
8
|
-
# This method is defined to be able to write
|
9
|
-
#
|
10
|
-
# @person.try(:name)
|
11
|
-
#
|
12
|
-
# instead of
|
13
|
-
#
|
14
|
-
# @person.name if @person
|
15
|
-
#
|
16
|
-
# +try+ calls can be chained:
|
17
|
-
#
|
18
|
-
# @person.try(:spouse).try(:name)
|
19
|
-
#
|
20
|
-
# instead of
|
21
|
-
#
|
22
|
-
# @person.spouse.name if @person && @person.spouse
|
23
|
-
#
|
24
|
-
# +try+ will also return +nil+ if the receiver does not respond to the method:
|
25
|
-
#
|
26
|
-
# @person.try(:non_existing_method) #=> nil
|
27
|
-
#
|
28
|
-
# instead of
|
29
|
-
#
|
30
|
-
# @person.non_existing_method if @person.respond_to?(:non_existing_method) #=> nil
|
31
|
-
#
|
32
|
-
# +try+ returns +nil+ when called on +nil+ regardless of whether it responds
|
33
|
-
# to the method:
|
34
|
-
#
|
35
|
-
# nil.try(:to_i) # => nil, rather than 0
|
36
|
-
#
|
37
|
-
# Arguments and blocks are forwarded to the method if invoked:
|
38
|
-
#
|
39
|
-
# @posts.try(:each_slice, 2) do |a, b|
|
40
|
-
# ...
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# The number of arguments in the signature must match. If the object responds
|
44
|
-
# to the method the call is attempted and +ArgumentError+ is still raised
|
45
|
-
# in case of argument mismatch.
|
46
|
-
#
|
47
|
-
# If +try+ is called without arguments it yields the receiver to a given
|
48
|
-
# block unless it is +nil+:
|
49
|
-
#
|
50
|
-
# @person.try do |p|
|
51
|
-
# ...
|
52
|
-
# end
|
53
|
-
#
|
54
|
-
# You can also call try with a block without accepting an argument, and the block
|
55
|
-
# will be instance_eval'ed instead:
|
56
|
-
#
|
57
|
-
# @person.try { upcase.truncate(50) }
|
58
|
-
#
|
59
|
-
# Please also note that +try+ is defined on +Object+. Therefore, it won't work
|
60
|
-
# with instances of classes that do not have +Object+ among their ancestors,
|
61
|
-
# like direct subclasses of +BasicObject+. For example, using +try+ with
|
62
|
-
# +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
|
63
|
-
# the delegator itself.
|
64
|
-
def try(*a, &b)
|
65
|
-
try!(*a, &b) if a.empty? || respond_to?(a.first)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Same as #try, but will raise a NoMethodError exception if the receiver is not +nil+ and
|
69
|
-
# does not implement the tried method.
|
70
|
-
|
71
|
-
def try!(*a, &b)
|
72
|
-
if a.empty? && block_given?
|
73
|
-
if b.arity == 0
|
74
|
-
instance_eval(&b)
|
75
|
-
else
|
76
|
-
yield self
|
77
|
-
end
|
78
|
-
else
|
79
|
-
public_send(*a, &b)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
class NilClass
|
85
|
-
# Calling +try+ on +nil+ always returns +nil+.
|
86
|
-
# It becomes especially helpful when navigating through associations that may return +nil+.
|
87
|
-
#
|
88
|
-
# nil.try(:name) # => nil
|
89
|
-
#
|
90
|
-
# Without +try+
|
91
|
-
# @person && @person.children.any? && @person.children.first.name
|
92
|
-
#
|
93
|
-
# With +try+
|
94
|
-
# @person.try(:children).try(:first).try(:name)
|
95
|
-
def try(*args)
|
96
|
-
nil
|
97
|
-
end
|
98
|
-
|
99
|
-
def try!(*args)
|
100
|
-
nil
|
101
|
-
end
|
102
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
require 'core_ext/try'
|
3
|
-
|
4
|
-
module GenesisCollector
|
5
|
-
class LshwParser
|
6
|
-
attr_reader :doc
|
7
|
-
|
8
|
-
def initialize(doc)
|
9
|
-
@doc = Nokogiri::XML(doc)
|
10
|
-
end
|
11
|
-
|
12
|
-
def cpus
|
13
|
-
@cpus ||= doc.xpath("//node[@class='processor']").map do |cpu|
|
14
|
-
{
|
15
|
-
description: cpu.at_xpath('.//product').try(:text) || cpu.at_xpath('.//description').try(:text),
|
16
|
-
cores: cpu.at_xpath(".//configuration/setting[@id='cores']/@value").try(:value).try(:to_i),
|
17
|
-
threads: cpu.at_xpath(".//configuration/setting[@id='threads']/@value").try(:value).try(:to_i),
|
18
|
-
speed: cpu.at_xpath('.//size').try(:text).try(:to_i),
|
19
|
-
vendor_name: cpu.at_xpath('.//vendor').try(:text),
|
20
|
-
physid: cpu.at_xpath('.//physid').try(:text).try(:to_i)
|
21
|
-
}
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def memories
|
26
|
-
@memories ||= doc.xpath("//node[@class='memory']/*[@id]").map do |memory|
|
27
|
-
mem_size = memory.at_xpath('.//size')
|
28
|
-
{
|
29
|
-
size: mem_size.nil? ? 0 : mem_size.text.to_i,
|
30
|
-
description: memory.at_xpath('.//description').text,
|
31
|
-
bank: memory.at_xpath('.//physid').text.to_i,
|
32
|
-
slot: memory.at_xpath('.//slot').try(:text),
|
33
|
-
product: memory.at_xpath('.//product').try(:text),
|
34
|
-
vendor_name: memory.at_xpath('.//vendor').try(:text)
|
35
|
-
}
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def network_interfaces
|
40
|
-
@network_interfaces ||= doc.xpath("//node[@class='network']").map do |network_interface|
|
41
|
-
{
|
42
|
-
name: network_interface.at_xpath('.//logicalname').try(:text),
|
43
|
-
description: network_interface.at_xpath('.//description').try(:text),
|
44
|
-
mac_address: network_interface.at_xpath('.//serial').try(:text),
|
45
|
-
product: network_interface.at_xpath('.//product').try(:text),
|
46
|
-
vendor_name: network_interface.at_xpath('.//vendor').try(:text),
|
47
|
-
driver: network_interface.at_xpath(".//configuration//setting[@id='driver']/@value").try(:text),
|
48
|
-
driver_version: network_interface.at_xpath(".//configuration//setting[@id='driverversion']/@value").try(:text),
|
49
|
-
duplex: network_interface.at_xpath(".//configuration//setting[@id='duplex']/@value").try(:text),
|
50
|
-
link_type: network_interface.at_xpath(".//configuration//setting[@id='port']/@value").try(:text)
|
51
|
-
}
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|