genesis_collector 0.1.5 → 0.1.6

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
  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