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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0fbdafc98930083ecc42e3fd607e215cdb17843
4
- data.tar.gz: 9073a58f0c2937840056caa65553ebd0050bc7da
3
+ metadata.gz: 208f4ec96b38ba5d57e06c70ec9cf0771b566da9
4
+ data.tar.gz: 08e9f2d38f9a0df9bbf83080dfb086b499c3cb5d
5
5
  SHA512:
6
- metadata.gz: 7ead4f71b8b42e17d485743bcedc8d9fcaa21a7d1fab6196a17ae3113bfc9f7caeb742e1d4bbb81378b29ec4b0c5178283860a9c9eba082976bcd2283f950148
7
- data.tar.gz: 492ba07a9f96535fb86ccdbaed21b6e6af6bc21dec9e044e3084284a86f7bd6fc31df079357e6835545bac0c0d2f5e91f304eaa47d4806e4fa766f56afdb87a2
6
+ metadata.gz: 786aa2d00b95c9bd341adc132166346c1e764a25ea8051d0d9373b6b52e1a2898dbe83cef3fad4d8765045e48546a3e4d39ec9c66208f583fe7e0092cbb4fc49
7
+ data.tar.gz: 12c5f4036cf0908efaded80a491143ef29f9e15ed98d9d27b2520bb70ab02d0862300075220335f0640030d737b78c20e95ed62c282aef46d85521875bda0bd6
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ sudo: false
3
+ rvm:
4
+ - 1.9
5
+ - 2.0
6
+ - 2.1.8
7
+ - 2.2.4
8
+ - 2.3.0
9
+
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: 1.9
13
+ - rvm: 2.0
data/Rakefile CHANGED
@@ -1,2 +1,4 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ RSpec::Core::RakeTask.new(:spec)
2
4
  task default: :spec
@@ -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.add_dependency 'nokogiri'
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] = get_lshw_data.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] = get_lshw_data.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
@@ -1,3 +1,3 @@
1
1
  module GenesisCollector
2
- VERSION = '0.1.5'
2
+ VERSION = '0.1.6'
3
3
  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.5
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-08 00:00:00.000000000 Z
11
+ date: 2016-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: nokogiri
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: :runtime
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,11 +0,0 @@
1
- require 'genesis_collector/lshw_parser'
2
-
3
- module GenesisCollector
4
- module Lshw
5
-
6
- def get_lshw_data
7
- @lshw_data ||= GenesisCollector::LshwParser.new(shellout_with_timeout('lshw -xml', 40).strip)
8
- end
9
-
10
- end
11
- 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