ohai 0.5.8 → 0.6.0.beta.0

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.
Files changed (52) hide show
  1. data/Rakefile +16 -48
  2. data/bin/ohai +1 -1
  3. data/lib/ohai.rb +1 -3
  4. data/lib/ohai/mash.rb +211 -0
  5. data/lib/ohai/mixin/command.rb +157 -44
  6. data/lib/ohai/mixin/ec2_metadata.rb +87 -0
  7. data/lib/ohai/plugins/c.rb +16 -13
  8. data/lib/ohai/plugins/chef.rb +2 -1
  9. data/lib/ohai/plugins/cloud.rb +25 -0
  10. data/lib/ohai/plugins/darwin/network.rb +10 -1
  11. data/lib/ohai/plugins/dmi.rb +100 -37
  12. data/lib/ohai/plugins/dmi_common.rb +117 -0
  13. data/lib/ohai/plugins/ec2.rb +12 -61
  14. data/lib/ohai/plugins/eucalyptus.rb +65 -0
  15. data/lib/ohai/plugins/freebsd/network.rb +11 -2
  16. data/lib/ohai/plugins/java.rb +4 -4
  17. data/lib/ohai/plugins/linux/filesystem.rb +24 -0
  18. data/lib/ohai/plugins/linux/network.rb +14 -1
  19. data/lib/ohai/plugins/linux/platform.rb +3 -0
  20. data/lib/ohai/plugins/linux/virtualization.rb +28 -6
  21. data/lib/ohai/plugins/netbsd/network.rb +10 -1
  22. data/lib/ohai/plugins/network.rb +3 -1
  23. data/lib/ohai/plugins/ohai.rb +1 -0
  24. data/lib/ohai/plugins/openbsd/network.rb +10 -1
  25. data/lib/ohai/plugins/ruby.rb +1 -1
  26. data/lib/ohai/plugins/sigar/filesystem.rb +2 -0
  27. data/lib/ohai/plugins/solaris2/dmi.rb +176 -0
  28. data/lib/ohai/plugins/solaris2/filesystem.rb +101 -0
  29. data/lib/ohai/plugins/solaris2/hostname.rb +10 -1
  30. data/lib/ohai/plugins/solaris2/network.rb +6 -1
  31. data/lib/ohai/plugins/solaris2/uptime.rb +36 -0
  32. data/lib/ohai/plugins/solaris2/virtualization.rb +91 -0
  33. data/lib/ohai/plugins/virtualization.rb +1 -1
  34. data/lib/ohai/plugins/windows/network.rb +17 -11
  35. data/lib/ohai/system.rb +22 -32
  36. data/lib/ohai/version.rb +23 -0
  37. data/spec/ohai/plugins/c_spec.rb +58 -7
  38. data/spec/ohai/plugins/cloud_spec.rb +24 -0
  39. data/spec/ohai/plugins/dmi_spec.rb +107 -47
  40. data/spec/ohai/plugins/ec2_spec.rb +3 -3
  41. data/spec/ohai/plugins/eucalyptus_spec.rb +84 -0
  42. data/spec/ohai/plugins/java_spec.rb +55 -2
  43. data/spec/ohai/plugins/linux/platform_spec.rb +13 -0
  44. data/spec/ohai/plugins/linux/virtualization_spec.rb +47 -6
  45. data/spec/ohai/plugins/perl_spec.rb +15 -14
  46. data/spec/ohai/plugins/rackspace_spec.rb +14 -14
  47. data/spec/ohai/plugins/solaris2/hostname_spec.rb +3 -8
  48. data/spec/ohai/plugins/solaris2/kernel_spec.rb +6 -6
  49. data/spec/ohai/plugins/solaris2/network_spec.rb +22 -22
  50. data/spec/ohai/plugins/solaris2/virtualization_spec.rb +133 -0
  51. data/spec/spec_helper.rb +5 -13
  52. metadata +182 -179
@@ -0,0 +1,101 @@
1
+ #
2
+ # Author:: Kurt Yoder (ktyopscode@yoderhome.com)
3
+ # Copyright:: Copyright (c) 2008 Opscode, 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
+ provides "filesystem"
20
+
21
+ fs = Mash.new
22
+
23
+ # Grab filesystem data from df
24
+ popen4("df -ka") do |pid, stdin, stdout, stderr|
25
+ stdin.close
26
+ stdout.each do |line|
27
+ case line
28
+ when /^Filesystem\s+kbytes/
29
+ next
30
+ when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/
31
+ filesystem = $1
32
+ fs[filesystem] = Mash.new
33
+ fs[filesystem][:kb_size] = $2
34
+ fs[filesystem][:kb_used] = $3
35
+ fs[filesystem][:kb_available] = $4
36
+ fs[filesystem][:percent_used] = $5
37
+ fs[filesystem][:mount] = $6
38
+ end
39
+ end
40
+ end
41
+
42
+ # Grab file system type from df (must be done separately)
43
+ popen4("df -na") do |pid, stdin, stdout, stderr|
44
+ stdin.close
45
+ stdout.each do |line|
46
+ next unless (line =~ /^(.+?)\s*: (\S+)\s*$/)
47
+ mount = $1
48
+ fs.each { |filesystem,fs_attributes|
49
+ next unless (fs_attributes[:mount] == mount)
50
+ fs[filesystem][:fs_type] = $2
51
+ }
52
+ end
53
+ end
54
+
55
+ # Grab mount information from /bin/mount
56
+ popen4("mount") do |pid, stdin, stdout, stderr|
57
+ stdin.close
58
+ stdout.each do |line|
59
+ next unless (line =~ /^(.+?) on (.+?) (.+?) on (.+?)$/)
60
+ filesystem = $2
61
+ fs[filesystem] = Mash.new unless fs.has_key?(filesystem)
62
+ fs[filesystem][:mount] = $1
63
+ fs[filesystem][:mount_time] = $4 # $4 must come before "split", else it becomes nil
64
+ fs[filesystem][:mount_options] = $3.split("/")
65
+ end
66
+ end
67
+
68
+ # Grab any zfs data from "zfs get"
69
+ zfs = Mash.new
70
+ popen4("zfs get -p -H all") do |pid, stdin, stdout, stderr|
71
+ stdin.close
72
+ stdout.each do |line|
73
+ next unless (line =~ /^([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)$/)
74
+ filesystem = $1
75
+ zfs[filesystem] = Mash.new unless zfs.has_key?(filesystem)
76
+ zfs[filesystem][:values] = Mash.new unless zfs[filesystem].has_key?('values')
77
+ zfs[filesystem][:sources] = Mash.new unless zfs[filesystem].has_key?('sources')
78
+ zfs[filesystem][:values][$2] = $3
79
+ zfs[filesystem][:sources][$2] = $4.chomp
80
+ end
81
+ end
82
+ zfs.each { |filesystem, attributes|
83
+ fs[filesystem] = Mash.new unless fs.has_key?(filesystem)
84
+ fs[filesystem][:fs_type] = 'zfs'
85
+ fs[filesystem][:mount] = attributes[:values][:mountpoint] if attributes[:values].has_key?('mountpoint')
86
+ fs[filesystem][:zfs_values] = attributes[:values]
87
+ fs[filesystem][:zfs_sources] = attributes[:sources]
88
+ # find all zfs parents
89
+ parents = filesystem.split('/')
90
+ zfs_parents = []
91
+ (0 .. parents.length - 1).to_a.each { |parent_indexes|
92
+ next_parent = parents[0 .. parent_indexes].join('/')
93
+ zfs_parents.push(next_parent)
94
+ }
95
+ zfs_parents.pop
96
+ fs[filesystem][:zfs_parents] = zfs_parents
97
+ fs[filesystem][:zfs_zpool] = (zfs_parents.length == 0)
98
+ }
99
+
100
+ # Set the filesystem data
101
+ filesystem fs
@@ -17,9 +17,18 @@
17
17
  # See the License for the specific language governing permissions and
18
18
  # limitations under the License.
19
19
  #
20
+ require 'socket'
20
21
 
21
22
  provides "hostname", "fqdn"
22
23
 
23
24
  hostname from("hostname")
24
25
 
25
- fqdn(from("hostname") + "." + from("domainname"))
26
+ fqdn_lookup = Socket.getaddrinfo(hostname, nil, nil, nil, nil, Socket::AI_CANONNAME).first[2]
27
+
28
+ if fqdn_lookup.split('.').length > 1
29
+ # we recieved an fqdn
30
+ fqdn fqdn_lookup
31
+ else
32
+ # default to assembling one
33
+ fqdn(from("hostname") + "." + from("domainname"))
34
+ end
@@ -142,7 +142,7 @@ end
142
142
 
143
143
  network[:interfaces] = iface
144
144
 
145
- popen4("route get default") do |pid, stdin, stdout, stderr|
145
+ popen4("route -n get default") do |pid, stdin, stdout, stderr|
146
146
  stdin.close
147
147
  route_get = stdout.read
148
148
  matches = /interface: (\S+)/.match(route_get)
@@ -150,5 +150,10 @@ popen4("route get default") do |pid, stdin, stdout, stderr|
150
150
  Ohai::Log.debug("found gateway device: #{$1}")
151
151
  network[:default_interface] = matches[1]
152
152
  end
153
+ matches = /gateway: (\S+)/.match(route_get)
154
+ if matches
155
+ Ohai::Log.debug("found gateway: #{$1}")
156
+ network[:default_gateway] = matches[1]
157
+ end
153
158
  end
154
159
 
@@ -0,0 +1,36 @@
1
+ #
2
+ # Author:: Kurt Yoder (<ktyopscode@yoderhome.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, 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
+ require 'date'
19
+ # It would be far better if we could include sys/uptime from sys-uptime RubyGem
20
+ # It would also be good if we could pull idle time; how do we do this on Solaris?
21
+
22
+ provides "uptime", "uptime_seconds"
23
+
24
+ # Example output:
25
+ # $ who -b
26
+ # . system boot Jul 9 17:51
27
+ popen4('who -b') do |pid, stdin, stdout, stderr|
28
+ stdin.close
29
+ stdout.each do |line|
30
+ if line =~ /.* boot (.+)/
31
+ uptime_seconds Time.now.to_i - DateTime.parse($1).strftime('%s').to_i
32
+ uptime self._seconds_to_human(uptime_seconds)
33
+ break
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,91 @@
1
+ #
2
+ # Author:: Sean Walbran (<seanwalbran@gmail.com>)
3
+ # Author:: Kurt Yoder (<ktyopscode@yoderhome.com>)
4
+ # Copyright:: Copyright (c) 2009 Opscode, Inc.
5
+ # Copyright:: Copyright (c) 2010 Kurt Yoder
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+
21
+ provides "virtualization"
22
+
23
+ virtualization Mash.new
24
+
25
+ # Detect KVM/QEMU from cpuinfo, report as KVM
26
+ psrinfo_path="/usr/sbin/psrinfo"
27
+ if File.exists?(psrinfo_path)
28
+ popen4(psrinfo_path + " -pv") do |pid, stdin, stdout, stderr|
29
+ stdin.close
30
+ psr_info = stdout.read
31
+ if psr_info =~ /QEMU Virtual CPU/
32
+ virtualization[:system] = "kvm"
33
+ virtualization[:role] = "guest"
34
+ end
35
+ end
36
+ end
37
+
38
+ # http://www.dmo.ca/blog/detecting-virtualization-on-linux
39
+ smbios_path="/usr/sbin/smbios"
40
+ if File.exists?(smbios_path)
41
+ popen4(smbios_path) do |pid, stdin, stdout, stderr|
42
+ stdin.close
43
+ dmi_info = stdout.read
44
+ case dmi_info
45
+ when /Manufacturer: Microsoft/
46
+ if dmi_info =~ /Product: Virtual Machine/
47
+ virtualization[:system] = "virtualpc"
48
+ virtualization[:role] = "guest"
49
+ end
50
+ when /Manufacturer: VMware/
51
+ if dmi_info =~ /Product: VMware Virtual Platform/
52
+ virtualization[:system] = "vmware"
53
+ virtualization[:role] = "guest"
54
+ end
55
+ else
56
+ nil
57
+ end
58
+ end
59
+ end
60
+
61
+ if File.executable?('/usr/sbin/zoneadm')
62
+ zones = Mash.new
63
+
64
+ popen4("zoneadm list -pc") do |pid, stdin, stdout, stderr|
65
+ stdin.close
66
+ stdout.each{ |line|
67
+ info = line.chomp.split(/:/)
68
+ zones[info[1]] = {
69
+ 'id' => info[0],
70
+ 'state' => info[2],
71
+ 'root' => info[3],
72
+ 'uuid' => info[4],
73
+ 'brand' => info[5],
74
+ 'ip' => info[6],
75
+ }
76
+ }
77
+
78
+ if (zones.length == 1)
79
+ first_zone = zones.keys[0]
80
+ unless( first_zone == 'global')
81
+ virtualization[:system] = 'zone'
82
+ virtualization[:role] = 'guest'
83
+ virtualization[:guest_uuid] = zones[first_zone]['uuid']
84
+ end
85
+ elsif (zones.length > 1)
86
+ virtualization[:system] = 'zone'
87
+ virtualization[:role] = 'host'
88
+ virtualization[:guests] = zones
89
+ end
90
+ end
91
+ end
@@ -25,7 +25,7 @@ unless virtualization.nil? || !(virtualization[:role].eql?("host"))
25
25
  require 'libvirt'
26
26
  require 'hpricot'
27
27
 
28
- emu = (virtualization[:emulator].eql?('kvm') ? 'qemu' : virtualization[:emulator])
28
+ emu = (virtualization[:system].eql?('kvm') ? 'qemu' : virtualization[:system])
29
29
  virtualization[:libvirt_version] = Libvirt::version(emu)[0].to_s
30
30
 
31
31
  virtconn = Libvirt::open_read_only("#{emu}:///system")
@@ -16,6 +16,8 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
+ provides "network"
20
+
19
21
  require 'ruby-wmi'
20
22
 
21
23
  def encaps_lookup(encap)
@@ -63,7 +65,7 @@ end
63
65
 
64
66
  iface_instance.keys.each do |i|
65
67
  if iface_config[i][:ip_enabled] and iface_instance[i][:net_connection_id] and iface_instance[i][:interface_index]
66
- cint = sprintf("0x%X", iface_instance[i][:interface_index])
68
+ cint = sprintf("0x%x", iface_instance[i][:interface_index]).downcase
67
69
  iface[cint] = Mash.new
68
70
  iface[cint][:configuration] = iface_config[i]
69
71
  iface[cint][:instance] = iface_instance[i]
@@ -94,20 +96,24 @@ iface_instance.keys.each do |i|
94
96
  iface[cint][:type] = iface[cint][:instance][:adapter_type]
95
97
  iface[cint][:arp] = {}
96
98
  iface[cint][:encapsulation] = encaps_lookup(iface[cint][:instance][:adapter_type])
99
+ if iface[cint][:configuration][:default_ip_gateway] != nil and iface[cint][:configuration][:default_ip_gateway].size > 0
100
+ network[:default_gateway] = iface[cint][:configuration][:default_ip_gateway].first
101
+ network[:default_interface] = cint
102
+ end
97
103
  end
98
104
  end
99
105
 
100
106
  cint=nil
101
- from("arp /a").split("\n").each do |line|
102
- if line == ""
103
- cint = nil
104
- end
105
- if line =~ /^Interface:\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+[-]+\s+(0x\d+)/
106
- cint = $2
107
- end
108
- next unless iface[cint]
109
- if line =~ /^\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([a-fA-F0-9\:-]+)/
110
- iface[cint][:arp][$1] = $2.gsub("-",":").downcase
107
+ status, stdout, stderr = run_command(:command => "arp -a")
108
+ if status == 0
109
+ stdout.each do |line|
110
+ if line =~ /^Interface:\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+[-]+\s+(0x\S+)/
111
+ cint = $2.downcase
112
+ end
113
+ next unless iface[cint]
114
+ if line =~ /^\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([a-fA-F0-9\:-]+)/
115
+ iface[cint][:arp][$1] = $2.gsub("-",":").downcase
116
+ end
111
117
  end
112
118
  end
113
119
 
data/lib/ohai/system.rb CHANGED
@@ -16,22 +16,13 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'extlib'
19
+ require 'ohai/mash'
20
20
  require 'ohai/log'
21
21
  require 'ohai/mixin/from_file'
22
22
  require 'ohai/mixin/command'
23
23
  require 'ohai/mixin/string'
24
24
 
25
- begin
26
- require 'json'
27
- rescue LoadError
28
- begin
29
- require 'json/pure'
30
- rescue LoadError
31
- STDERR.puts "No valid JSON library detected, please install one of 'json' or 'json_pure'."
32
- exit -2
33
- end
34
- end
25
+ require 'yajl'
35
26
 
36
27
  module Ohai
37
28
  class System
@@ -72,7 +63,7 @@ module Ohai
72
63
  def from(cmd)
73
64
  status, stdout, stderr = run_command(:command => cmd)
74
65
  return "" if stdout.nil? || stdout.empty?
75
- stdout.chomp!.strip
66
+ stdout.strip
76
67
  end
77
68
 
78
69
  def provides(*paths)
@@ -198,8 +189,10 @@ module Ohai
198
189
  Ohai::Log.debug("Loading plugin #{plugin_name}")
199
190
  from_file(check_path)
200
191
  return true
201
- rescue IOError => e
192
+ rescue Errno::ENOENT => e
202
193
  Ohai::Log.debug("No #{plugin_name} at #{check_path}")
194
+ rescue SystemExit, Interrupt
195
+ raise
203
196
  rescue Exception,Errno::ENOENT => e
204
197
  Ohai::Log.debug("Plugin #{plugin_name} threw exception #{e.inspect} #{e.backtrace.join("\n")}")
205
198
  end
@@ -211,36 +204,33 @@ module Ohai
211
204
  alias :_require_plugin :require_plugin
212
205
 
213
206
  # Serialize this object as a hash
214
- def to_json(*a)
215
- output = @data.clone
216
- output["json_class"] = self.class.name
217
- output.to_json(*a)
207
+ def to_json
208
+ Yajl::Encoder.new.encode(@data)
218
209
  end
219
210
 
220
211
  # Pretty Print this object as JSON
221
- def json_pretty_print
222
- JSON.pretty_generate(@data)
212
+ def json_pretty_print(item=nil)
213
+ Yajl::Encoder.new(:pretty => true).encode(item || @data)
223
214
  end
224
215
 
225
216
  def attributes_print(a)
226
- raise ArgumentError, "I cannot find an attribute named #{a}!" unless @data.has_key?(a)
217
+ data = @data
218
+ a.split("/").each do |part|
219
+ data = data[part]
220
+ end
221
+ raise ArgumentError, "I cannot find an attribute named #{a}!" if data.nil?
227
222
  case a
228
223
  when Hash,Mash,Array
229
- JSON.pretty_generate(@data[a])
224
+ json_pretty_print(data)
230
225
  when String
231
- JSON.pretty_generate(@data[a].to_a)
226
+ if data.respond_to?(:lines)
227
+ json_pretty_print(data.lines.to_a)
228
+ else
229
+ json_pretty_print(data.to_a)
230
+ end
232
231
  else
233
- raise ArgumentError, "I can only generate JSON for Hashes, Mashes, Arrays and Strings. You fed me a #{@data[a].class}!"
234
- end
235
- end
236
-
237
- # Create an Ohai::System from JSON
238
- def self.json_create(o)
239
- ohai = new
240
- o.each do |key, value|
241
- ohai.data[key] = value unless key == "json_class"
232
+ raise ArgumentError, "I can only generate JSON for Hashes, Mashes, Arrays and Strings. You fed me a #{data.class}!"
242
233
  end
243
- ohai
244
234
  end
245
235
 
246
236
  def method_missing(name, *args)
@@ -0,0 +1,23 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, 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
+ module Ohai
20
+ OHAI_ROOT = File.expand_path(File.dirname(__FILE__))
21
+ VERSION = '0.6.0.beta.0'
22
+ end
23
+