diff options
141 files changed, 7345 insertions, 21 deletions
diff --git a/lib/ohai/loader.rb b/lib/ohai/loader.rb index 72e46dbc..54d22620 100644 --- a/lib/ohai/loader.rb +++ b/lib/ohai/loader.rb @@ -28,35 +28,58 @@ module Ohai def initialize(controller) @attributes = controller.attributes @plugins = controller.plugins + @v6plugins = controller.v6plugins @sources = controller.sources end def load_plugin(plugin_path, plugin_name=nil) - clean_up(plugin_path) if @sources.has_key?(plugin_path) - - plugin = nil - - begin - plugin = from_file(plugin_path) - rescue SystemExit, Interrupt - raise - rescue Exception, Errno::ENOENT => e - Ohai::Log.debug("Plugin #{plugin_name} threw exception #{e.inspect} #{e.backtrace.join("\n")}") - return - end + if version6?(plugin_path) + save_plugin(plugin_path) + else + clean_up(plugin_path) if @sources.has_key?(plugin_path) + + plugin = nil - if plugin.nil? - Ohai::Log.debug("Unable to load plugin at #{plugin_path}") - return - end + begin + plugin = from_file(plugin_path) + rescue SystemExit, Interrupt + raise + rescue Exception, Errno::ENOENT => e + Ohai::Log.debug("Plugin #{plugin_name} threw exception #{e.inspect} #{e.backtrace.join("\n")}") + return + end - plugin_key = plugin_name || plugin.to_s - register_plugin(plugin, plugin_path, plugin_key) - collect_provides(plugin, plugin_key) + if plugin.nil? + Ohai::Log.debug("Unable to load plugin at #{plugin_path}") + return + end + + plugin_key = plugin_name || plugin.to_s + register_plugin(plugin, plugin_path, plugin_key) + collect_provides(plugin, plugin_key) + end end private + def version6?(plugin_path) + File.open(plugin_path) { |f| f.grep(/Ohai\.plugin/).empty? } + end + + def save_plugin(plugin_path) + unless @sources.has_key?(plugin_path) + Ohai::Config[:plugin_path].each do |path| + file_regex = Regexp.new("#{File.expand_path(path)}#{File::SEPARATOR}(.+).rb$") + md = file_regex.match(plugin_path) + if md + plugin_name = md[1].gsub(File::SEPARATOR, "::") + @v6plugins[plugin_name] = plugin_path + @sources[plugin_path] = plugin_name + end + end + end + end + def clean_up(file) key = @sources[file] @plugins[key][:provides].each do |attr| diff --git a/lib/ohai/system.rb b/lib/ohai/system.rb index 07cca65e..f68b8073 100644 --- a/lib/ohai/system.rb +++ b/lib/ohai/system.rb @@ -33,6 +33,7 @@ module Ohai attr_accessor :data attr_reader :attributes attr_reader :plugins + attr_reader :v6plugins attr_reader :sources attr_reader :hints @@ -40,6 +41,7 @@ module Ohai @data = Mash.new @attributes = Hash.new @plugins = Mash.new + @v6plugins = Hash.new @sources = Hash.new @hints = Hash.new @plugin_path = "" @@ -51,7 +53,7 @@ module Ohai def load_plugins loader = Ohai::Loader.new(self) - + Ohai::Config[:plugin_path].each do |path| [ Dir[File.join(path, '*')], @@ -209,6 +211,5 @@ module Ohai end end - end end diff --git a/spec/data/plugins/mix/plugin6.rb b/spec/data/plugins/mix/plugin6.rb new file mode 100644 index 00000000..bfab8a72 --- /dev/null +++ b/spec/data/plugins/mix/plugin6.rb @@ -0,0 +1,5 @@ +provides "plugin6" + +require_plugin "simple6" + +plugin6 "this is a version 6 plugin" diff --git a/spec/data/plugins/mix/plugin7.rb b/spec/data/plugins/mix/plugin7.rb new file mode 100644 index 00000000..963a10d1 --- /dev/null +++ b/spec/data/plugins/mix/plugin7.rb @@ -0,0 +1,7 @@ +Ohai.plugin do + provides "plugin7" + + collect_data do + plugin7 "this is a version 7 plugin" + end +end diff --git a/spec/data/plugins/mix/simple6.rb b/spec/data/plugins/mix/simple6.rb new file mode 100644 index 00000000..a0a04248 --- /dev/null +++ b/spec/data/plugins/mix/simple6.rb @@ -0,0 +1 @@ +provides "simple6" diff --git a/spec/data/plugins/mix/simple7.rb b/spec/data/plugins/mix/simple7.rb new file mode 100644 index 00000000..e4d0aba9 --- /dev/null +++ b/spec/data/plugins/mix/simple7.rb @@ -0,0 +1,3 @@ +Ohai.plugin do + provides "simple7" +end diff --git a/spec/data/plugins/v6/aix/cpu.rb b/spec/data/plugins/v6/aix/cpu.rb new file mode 100644 index 00000000..32b2dc91 --- /dev/null +++ b/spec/data/plugins/v6/aix/cpu.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::cpu" diff --git a/spec/data/plugins/v6/aix/filesystem.rb b/spec/data/plugins/v6/aix/filesystem.rb new file mode 100644 index 00000000..8322ee0b --- /dev/null +++ b/spec/data/plugins/v6/aix/filesystem.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::filesystem" diff --git a/spec/data/plugins/v6/aix/hostname.rb b/spec/data/plugins/v6/aix/hostname.rb new file mode 100644 index 00000000..805b4734 --- /dev/null +++ b/spec/data/plugins/v6/aix/hostname.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::hostname" diff --git a/spec/data/plugins/v6/aix/memory.rb b/spec/data/plugins/v6/aix/memory.rb new file mode 100644 index 00000000..dd3532fb --- /dev/null +++ b/spec/data/plugins/v6/aix/memory.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::memory" diff --git a/spec/data/plugins/v6/aix/network.rb b/spec/data/plugins/v6/aix/network.rb new file mode 100644 index 00000000..7071abef --- /dev/null +++ b/spec/data/plugins/v6/aix/network.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::network" diff --git a/spec/data/plugins/v6/aix/platform.rb b/spec/data/plugins/v6/aix/platform.rb new file mode 100644 index 00000000..bea329d6 --- /dev/null +++ b/spec/data/plugins/v6/aix/platform.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::platform" diff --git a/spec/data/plugins/v6/aix/ps.rb b/spec/data/plugins/v6/aix/ps.rb new file mode 100644 index 00000000..9532014a --- /dev/null +++ b/spec/data/plugins/v6/aix/ps.rb @@ -0,0 +1,23 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "command/ps" + +require_plugin 'command' + +command[:ps] = 'ps -ef' diff --git a/spec/data/plugins/v6/aix/uptime.rb b/spec/data/plugins/v6/aix/uptime.rb new file mode 100644 index 00000000..23aa89f3 --- /dev/null +++ b/spec/data/plugins/v6/aix/uptime.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::uptime" diff --git a/spec/data/plugins/v6/azure.rb b/spec/data/plugins/v6/azure.rb new file mode 100644 index 00000000..d13a388f --- /dev/null +++ b/spec/data/plugins/v6/azure.rb @@ -0,0 +1,13 @@ + +provides "azure" + + +azure_metadata_from_hints = hint?('azure') +if azure_metadata_from_hints + Ohai::Log.debug("azure_metadata_from_hints is present.") + azure Mash.new + azure_metadata_from_hints.each {|k, v| azure[k] = v } +else + Ohai::Log.debug("No hints present for azure.") + false +end
\ No newline at end of file diff --git a/spec/data/plugins/v6/c.rb b/spec/data/plugins/v6/c.rb new file mode 100644 index 00000000..3e05aa06 --- /dev/null +++ b/spec/data/plugins/v6/c.rb @@ -0,0 +1,110 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'rbconfig' + +provides "languages/c" + +require_plugin "languages" + +c = Mash.new + +#gcc +status, stdout, stderr = run_command(:no_status_check => true, :command => "gcc -v") +if status == 0 + description = stderr.split($/).last + output = description.split + if output.length >= 3 + c[:gcc] = Mash.new + c[:gcc][:version] = output[2] + c[:gcc][:description] = description + end +end + +#glibc +["/lib/libc.so.6", "/lib64/libc.so.6"].each do |glibc| + status, stdout, stderr = run_command(:no_status_check => true, :command => glibc) + if status == 0 + description = stdout.split($/).first + if description =~ /(\d+\.\d+\.?\d*)/ + c[:glibc] = Mash.new + c[:glibc][:version] = $1 + c[:glibc][:description] = description + end + break + end +end + +#ms cl +status, stdout, stderr = run_command(:no_status_check => true, :command => "cl /?") +if status == 0 + description = stderr.split($/).first + if description =~ /Compiler Version ([\d\.]+)/ + c[:cl] = Mash.new + c[:cl][:version] = $1 + c[:cl][:description] = description + end +end + +#ms vs +status, stdout, stderr = run_command(:no_status_check => true, :command => "devenv.com /?") +if status == 0 + lines = stdout.split($/) + description = lines[0].length == 0 ? lines[1] : lines[0] + if description =~ /Visual Studio Version ([\d\.]+)/ + c[:vs] = Mash.new + c[:vs][:version] = $1.chop + c[:vs][:description] = description + end +end + +#ibm xlc +status, stdout, stderr = run_command(:no_status_check => true, :command => "xlc -qversion") +if status == 0 or (status >> 8) == 249 + description = stdout.split($/).first + if description =~ /V(\d+\.\d+)/ + c[:xlc] = Mash.new + c[:xlc][:version] = $1 + c[:xlc][:description] = description.strip + end +end + +#sun pro +status, stdout, stderr = run_command(:no_status_check => true, :command => "cc -V -flags") +if status == 0 + output = stderr.split + if stderr =~ /^cc: Sun C/ && output.size >= 4 + c[:sunpro] = Mash.new + c[:sunpro][:version] = output[3] + c[:sunpro][:description] = stderr.chomp + end +end + +#hpux cc +status, stdout, stderr = run_command(:no_status_check => true, :command => "what /opt/ansic/bin/cc") +if status == 0 + description = stdout.split($/).select { |line| line =~ /HP C Compiler/ }.first + if description + output = description.split + c[:hpcc] = Mash.new + c[:hpcc][:version] = output[1] if output.size >= 1 + c[:hpcc][:description] = description.strip + end +end + +languages[:c] = c if c.keys.length > 0 diff --git a/spec/data/plugins/v6/chef.rb b/spec/data/plugins/v6/chef.rb new file mode 100644 index 00000000..2b36a219 --- /dev/null +++ b/spec/data/plugins/v6/chef.rb @@ -0,0 +1,25 @@ +# +# Author:: Tollef Fog Heen <tfheen@err.no> +# Copyright:: Copyright (c) 2010 Tollef Fog Heen +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'chef/version' +provides "chef" + +self[:chef_packages] = Mash.new unless self[:chef_packages] +self[:chef_packages][:chef] = Mash.new +self[:chef_packages][:chef][:version] = Chef::VERSION +self[:chef_packages][:chef][:chef_root] = Chef::CHEF_ROOT diff --git a/spec/data/plugins/v6/cloud.rb b/spec/data/plugins/v6/cloud.rb new file mode 100644 index 00000000..9d0001af --- /dev/null +++ b/spec/data/plugins/v6/cloud.rb @@ -0,0 +1,247 @@ +# +# Author:: Cary Penniman (<cary@rightscale.com>) +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provides "cloud" + +require_plugin "ec2" +require_plugin "gce" +require_plugin "rackspace" +require_plugin "eucalyptus" +require_plugin "linode" +require_plugin "openstack" +require_plugin "azure" + +# Make top-level cloud hashes +# +def create_objects + cloud Mash.new + cloud[:public_ips] = Array.new + cloud[:private_ips] = Array.new +end +#--------------------------------------- +# Google Compute Engine (gce) +#-------------------------------------- + +def on_gce? + gce != nil +end +def get_gce_values + cloud[:public_ipv4] = [] + cloud[:local_ipv4] = [] + + public_ips = gce['network']["networkInterface"].collect do |interface| + if interface.has_key?('accessConfiguration') + interface['accessConfiguration'].collect{|ac| ac['externalIp']} + end + end.flatten.compact + + private_ips = gce['network']["networkInterface"].collect do |interface| + interface['ip'] + end.compact + + cloud[:public_ips] += public_ips + cloud[:private_ips] += private_ips + cloud[:public_ipv4] += public_ips + cloud[:public_hostname] = nil + cloud[:local_ipv4] += private_ips + cloud[:local_hostname] = gce['hostname'] + cloud[:provider] = "gce" +end + +# setup gce cloud +if on_gce? + create_objects + get_gce_values +end + +# ---------------------------------------- +# ec2 +# ---------------------------------------- + +# Is current cloud ec2? +# +# === Return +# true:: If ec2 Hash is defined +# false:: Otherwise +def on_ec2? + ec2 != nil +end + +# Fill cloud hash with ec2 values +def get_ec2_values + cloud[:public_ips] << ec2['public_ipv4'] + cloud[:private_ips] << ec2['local_ipv4'] + cloud[:public_ipv4] = ec2['public_ipv4'] + cloud[:public_hostname] = ec2['public_hostname'] + cloud[:local_ipv4] = ec2['local_ipv4'] + cloud[:local_hostname] = ec2['local_hostname'] + cloud[:provider] = "ec2" +end + +# setup ec2 cloud +if on_ec2? + create_objects + get_ec2_values +end + +# ---------------------------------------- +# rackspace +# ---------------------------------------- + +# Is current cloud rackspace? +# +# === Return +# true:: If rackspace Hash is defined +# false:: Otherwise +def on_rackspace? + rackspace != nil +end + +# Fill cloud hash with rackspace values +def get_rackspace_values + cloud[:public_ips] << rackspace['public_ipv4'] if rackspace['public_ipv4'] + cloud[:private_ips] << rackspace['local_ipv4'] if rackspace['local_ipv4'] + cloud[:public_ipv4] = rackspace['public_ipv4'] + cloud[:public_ipv6] = rackspace['public_ipv6'] + cloud[:public_hostname] = rackspace['public_hostname'] + cloud[:local_ipv4] = rackspace['local_ipv4'] + cloud[:local_ipv6] = rackspace['local_ipv6'] + cloud[:local_hostname] = rackspace['local_hostname'] + cloud[:provider] = "rackspace" +end + +# setup rackspace cloud +if on_rackspace? + create_objects + get_rackspace_values +end + +# ---------------------------------------- +# linode +# ---------------------------------------- + +# Is current cloud linode? +# +# === Return +# true:: If linode Hash is defined +# false:: Otherwise +def on_linode? + linode != nil +end + +# Fill cloud hash with linode values +def get_linode_values + cloud[:public_ips] << linode['public_ip'] + cloud[:private_ips] << linode['private_ip'] + cloud[:public_ipv4] = linode['public_ipv4'] + cloud[:public_hostname] = linode['public_hostname'] + cloud[:local_ipv4] = linode['local_ipv4'] + cloud[:local_hostname] = linode['local_hostname'] + cloud[:provider] = "linode" +end + +# setup linode cloud data +if on_linode? + create_objects + get_linode_values +end + +# ---------------------------------------- +# eucalyptus +# ---------------------------------------- + +# Is current cloud eucalyptus? +# +# === Return +# true:: If eucalyptus Hash is defined +# false:: Otherwise +def on_eucalyptus? + eucalyptus != nil +end + +def get_eucalyptus_values + cloud[:public_ips] << eucalyptus['public_ipv4'] + cloud[:private_ips] << eucalyptus['local_ipv4'] + cloud[:public_ipv4] = eucalyptus['public_ipv4'] + cloud[:public_hostname] = eucalyptus['public_hostname'] + cloud[:local_ipv4] = eucalyptus['local_ipv4'] + cloud[:local_hostname] = eucalyptus['local_hostname'] + cloud[:provider] = "eucalyptus" +end + +if on_eucalyptus? + create_objects + get_eucalyptus_values +end + +# ---------------------------------------- +# openstack +# ---------------------------------------- + +# Is current cloud openstack-based? +# +# === Return +# true:: If openstack Hash is defined +# false:: Otherwise +def on_openstack? + openstack != nil +end + +# Fill cloud hash with openstack values +def get_openstack_values + cloud[:public_ips] << openstack['public_ipv4'] + cloud[:private_ips] << openstack['local_ipv4'] + cloud[:public_ipv4] = openstack['public_ipv4'] + cloud[:public_hostname] = openstack['public_hostname'] + cloud[:local_ipv4] = openstack['local_ipv4'] + cloud[:local_hostname] = openstack['local_hostname'] + cloud[:provider] = openstack['provider'] +end + +# setup openstack cloud +if on_openstack? + create_objects + get_openstack_values +end + +# ---------------------------------------- +# azure +# ---------------------------------------- + +# Is current cloud azure? +# +# === Return +# true:: If azure Hash is defined +# false:: Otherwise +def on_azure? + azure != nil +end + +# Fill cloud hash with azure values +def get_azure_values + cloud[:vm_name] = azure["vm_name"] + cloud[:public_ips] << azure['public_ip'] + cloud[:public_fqdn] = azure['public_fqdn'] + cloud[:public_ssh_port] = azure['public_ssh_port'] if azure['public_ssh_port'] + cloud[:public_winrm_port] = azure['public_winrm_port'] if azure['public_winrm_port'] + cloud[:provider] = "azure" +end + +# setup azure cloud data +if on_azure? + create_objects + get_azure_values +end
\ No newline at end of file diff --git a/spec/data/plugins/v6/command.rb b/spec/data/plugins/v6/command.rb new file mode 100644 index 00000000..4578a385 --- /dev/null +++ b/spec/data/plugins/v6/command.rb @@ -0,0 +1,21 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "command" + +command Mash.new
\ No newline at end of file diff --git a/spec/data/plugins/v6/darwin/cpu.rb b/spec/data/plugins/v6/darwin/cpu.rb new file mode 100644 index 00000000..37c4c573 --- /dev/null +++ b/spec/data/plugins/v6/darwin/cpu.rb @@ -0,0 +1,23 @@ +# +# Author:: Nathan L Smith (<nlloyds@gmail.com>) +# Copyright:: Copyright (c) 2013 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "cpu" + +cpu Mash.new +cpu[:real] = from("sysctl -n hw.physicalcpu").to_i +cpu[:total] = from("sysctl -n hw.logicalcpu").to_i diff --git a/spec/data/plugins/v6/darwin/filesystem.rb b/spec/data/plugins/v6/darwin/filesystem.rb new file mode 100644 index 00000000..65abebff --- /dev/null +++ b/spec/data/plugins/v6/darwin/filesystem.rb @@ -0,0 +1,57 @@ +# +# Author:: Benjamin Black (<bb@opscode.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "filesystem" + +fs = Mash.new + +block_size = 0 +popen4("df") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^Filesystem\s+(\d+)-/ + block_size = $1.to_i + next + when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/ + filesystem = $1 + fs[filesystem] = Mash.new + fs[filesystem][:block_size] = block_size + fs[filesystem][:kb_size] = $2.to_i / (1024 / block_size) + fs[filesystem][:kb_used] = $3.to_i / (1024 / block_size) + fs[filesystem][:kb_available] = $4.to_i / (1024 / block_size) + fs[filesystem][:percent_used] = $5 + fs[filesystem][:mount] = $6 + end + end +end + +popen4("mount") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^(.+?) on (.+?) \((.+?), (.+?)\)$/ + filesystem = $1 + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem][:mount] = $2 + fs[filesystem][:fs_type] = $3 + fs[filesystem][:mount_options] = $4.split(/,\s*/) + end + end +end + +filesystem fs
\ No newline at end of file diff --git a/spec/data/plugins/v6/darwin/hostname.rb b/spec/data/plugins/v6/darwin/hostname.rb new file mode 100644 index 00000000..ca8e2757 --- /dev/null +++ b/spec/data/plugins/v6/darwin/hostname.rb @@ -0,0 +1,22 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "fqdn", "hostname" + +hostname from("hostname -s") +fqdn from("hostname")
\ No newline at end of file diff --git a/spec/data/plugins/v6/darwin/kernel.rb b/spec/data/plugins/v6/darwin/kernel.rb new file mode 100644 index 00000000..c4d50ffa --- /dev/null +++ b/spec/data/plugins/v6/darwin/kernel.rb @@ -0,0 +1,37 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "kernel" + +kernel[:os] = kernel[:name] + +if from("sysctl -n hw.optional.x86_64").to_i == 1 + kernel[:machine] = 'x86_64' +end + +kext = Mash.new +popen4("kextstat -k -l") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /(\d+)\s+(\d+)\s+0x[0-9a-f]+\s+0x([0-9a-f]+)\s+0x[0-9a-f]+\s+([a-zA-Z0-9\.]+) \(([0-9\.]+)\)/ + kext[$4] = { :version => $5, :size => $3.hex, :index => $1, :refcount => $2 } + end + end +end + +kernel[:modules] = kext diff --git a/spec/data/plugins/v6/darwin/network.rb b/spec/data/plugins/v6/darwin/network.rb new file mode 100644 index 00000000..cc2b1243 --- /dev/null +++ b/spec/data/plugins/v6/darwin/network.rb @@ -0,0 +1,197 @@ +# +# Author:: Benjamin Black (<bb@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "network", "counters/network" + +require 'scanf' + +from("route -n get default").split("\n").each do |line| + if line =~ /(\w+): ([\w\.]+)/ + case $1 + when "gateway" + network[:default_gateway] = $2 + when "interface" + network[:default_interface] = $2 + end + end +end + +def parse_media(media_string) + media = Hash.new + line_array = media_string.split(' ') + + 0.upto(line_array.length - 1) do |i| + unless line_array[i].eql?("none") + + if line_array[i + 1] =~ /^\<([a-zA-Z\-\,]+)\>$/ + media[line_array[i]] = Hash.new unless media.has_key?(line_array[i]) + if media[line_array[i]].has_key?("options") + $1.split(",").each do |opt| + media[line_array[i]]["options"] << opt unless media[line_array[i]]["options"].include?(opt) + end + else + media[line_array[i]]["options"] = $1.split(",") + end + else + if line_array[i].eql?("autoselect") + media["autoselect"] = Hash.new unless media.has_key?("autoselect") + media["autoselect"]["options"] = [] + end + end + else + media["none"] = { "options" => [] } + end + end + + media +end + +def encaps_lookup(ifname) + return "Loopback" if ifname.eql?("lo") + return "1394" if ifname.eql?("fw") + return "IPIP" if ifname.eql?("gif") + return "6to4" if ifname.eql?("stf") + return "dot1q" if ifname.eql?("vlan") + "Unknown" +end + +def scope_lookup(scope) + return "Node" if scope.eql?("::1") + return "Link" if scope.match(/^fe80\:/) + return "Site" if scope.match(/^fec0\:/) + "Global" +end + +def excluded_setting?(setting) + setting.match('_sw_cksum') +end + +def locate_interface(ifaces, ifname, mac) + return ifname unless ifaces[ifname].nil? + # oh well, time to go hunting! + return ifname.chop if ifname.match /\*$/ + ifaces.keys.each do |ifc| + ifaces[ifc][:addresses].keys.each do |addr| + return ifc if addr.eql? mac + end + end + + nil +end + +iface = Mash.new +popen4("ifconfig -a") do |pid, stdin, stdout, stderr| + stdin.close + cint = nil + stdout.each do |line| + if line =~ /^([0-9a-zA-Z\.\:\-]+): \S+ mtu (\d+)$/ + cint = $1 + iface[cint] = Mash.new unless iface[cint]; iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:mtu] = $2 + if line =~ /\sflags\=\d+\<((UP|BROADCAST|DEBUG|SMART|SIMPLEX|LOOPBACK|POINTOPOINT|NOTRAILERS|RUNNING|NOARP|PROMISC|ALLMULTI|SLAVE|MASTER|MULTICAST|DYNAMIC|,)+)\>\s/ + flags = $1.split(',') + else + flags = Array.new + end + iface[cint][:flags] = flags.flatten + if cint =~ /^(\w+)(\d+.*)/ + iface[cint][:type] = $1 + iface[cint][:number] = $2 + iface[cint][:encapsulation] = encaps_lookup($1) + end + end + if line =~ /^\s+ether ([0-9a-f\:]+)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "lladdr" } + iface[cint][:encapsulation] = "Ethernet" + end + if line =~ /^\s+lladdr ([0-9a-f\:]+)\s/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "lladdr" } + end + if line =~ /\s+inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) netmask 0x(([0-9a-f]){1,8})\s*$/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => $2.scanf('%2x'*4)*"."} + end + if line =~ /\s+inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) netmask 0x(([0-9a-f]){1,8}) broadcast (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => $2.scanf('%2x'*4)*".", "broadcast" => $4 } + end + if line =~ /\s+inet6 ([a-f0-9\:]+)(\s*|(\%[a-z0-9]+)\s*) prefixlen (\d+)\s*/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $4 , "scope" => scope_lookup($1) } + end + if line =~ /\s+inet6 ([a-f0-9\:]+)(\s*|(\%[a-z0-9]+)\s*) prefixlen (\d+) scopeid 0x([a-f0-9]+)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $4 , "scope" => scope_lookup($1) } + end + if line =~ /^\s+media: ((\w+)|(\w+ [a-zA-Z0-9\-\<\>]+)) status: (\w+)/ + iface[cint][:media] = Mash.new unless iface[cint][:media] + iface[cint][:media][:selected] = parse_media($1) + iface[cint][:status] = $4 + end + if line =~ /^\s+supported media: (.*)/ + iface[cint][:media] = Mash.new unless iface[cint][:media] + iface[cint][:media][:supported] = parse_media($1) + end + end +end + +popen4("arp -an") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^\S+ \((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) on ([a-zA-Z0-9\.\:\-]+).*\[(\w+)\]/ + # MAC addr really should be normalized to include all the zeroes. + next if iface[$3].nil? # this should never happen + iface[$3][:arp] = Mash.new unless iface[$3][:arp] + iface[$3][:arp][$1] = $2 + end + end +end + +settings = Mash.new +popen4("sysctl net") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^([a-zA-Z0-9\.\_]+)\: (.*)/ + # should normalize names between platforms for the same settings. + settings[$1] = $2 unless excluded_setting?($1) + end + end +end + +network[:settings] = settings +network[:interfaces] = iface + +net_counters = Mash.new +popen4("netstat -i -d -l -b -n") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^([a-zA-Z0-9\.\:\-\*]+)\s+\d+\s+\<[a-zA-Z0-9\#]+\>\s+([a-f0-9\:]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ || + line =~ /^([a-zA-Z0-9\.\:\-\*]+)\s+\d+\s+\<[a-zA-Z0-9\#]+\>(\s+)(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ + ifname = locate_interface(iface, $1, $2) + next if iface[ifname].nil? # this shouldn't happen, but just in case + net_counters[ifname] = Mash.new unless net_counters[ifname] + net_counters[ifname] = { :rx => { :bytes => $5, :packets => $3, :errors => $4, :drop => 0, :overrun => 0, :frame => 0, :compressed => 0, :multicast => 0 }, + :tx => { :bytes => $8, :packets => $6, :errors => $7, :drop => 0, :overrun => 0, :collisions => $9, :carrier => 0, :compressed => 0 } + } + end + end +end + +counters[:network][:interfaces] = net_counters diff --git a/spec/data/plugins/v6/darwin/platform.rb b/spec/data/plugins/v6/darwin/platform.rb new file mode 100644 index 00000000..0841aa96 --- /dev/null +++ b/spec/data/plugins/v6/darwin/platform.rb @@ -0,0 +1,38 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "platform", "platform_version", "platform_build", "platform_family" + +popen4("/usr/bin/sw_vers") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^ProductName:\s+(.+)$/ + macname = $1 + macname.downcase! + macname.gsub!(" ", "_") + platform macname + when /^ProductVersion:\s+(.+)$/ + platform_version $1 + when /^BuildVersion:\s+(.+)$/ + platform_build $1 + end + end +end + +platform_family "mac_os_x" diff --git a/spec/data/plugins/v6/darwin/ps.rb b/spec/data/plugins/v6/darwin/ps.rb new file mode 100644 index 00000000..16f2e536 --- /dev/null +++ b/spec/data/plugins/v6/darwin/ps.rb @@ -0,0 +1,23 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "command/ps" + +require_plugin 'command' + +command[:ps] = 'ps -ef'
\ No newline at end of file diff --git a/spec/data/plugins/v6/darwin/system_profiler.rb b/spec/data/plugins/v6/darwin/system_profiler.rb new file mode 100644 index 00000000..9eacd63d --- /dev/null +++ b/spec/data/plugins/v6/darwin/system_profiler.rb @@ -0,0 +1,70 @@ +# +# Author:: Benjamin Black (<bb@opscode.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +provides "system_profile" + +begin + require 'plist' + + system_profile Array.new + items Array.new + detail_level = { + 'mini' => [ + "SPParallelATAData", + "SPAudioData", + "SPBluetoothData", + "SPCardReaderData", + "SPDiagnosticsData", + "SPDiscBurningData", + "SPEthernetData", + "SPFibreChannelData", + "SPFireWireData", + "SPDisplaysData", + "SPHardwareRAIDData", + "SPMemoryData", + "SPModemData", + "SPNetworkData", + "SPPCIData", + "SPParallelSCSIData", + "SPPrintersSoftwareData", + "SPPrintersData", + "SPSASData", + "SPSerialATAData", + "SPSoftwareData", + "SPThunderboltData", + "SPUSBData", + "SPWWANData", + "SPAirPortData" + ], + 'full' => [ + "SPHardwareDataType" + ] + } + + detail_level.each do |level, data_types| + popen4("system_profiler -xml -detailLevel #{level} #{data_types.join(' ')}") do |pid, stdin, stdout, stderr| + stdin.close + Plist::parse_xml(stdout.read).each do |e| + items << e + end + end + end + + system_profile items.sort_by { |h| h['_dataType'] } +rescue LoadError => e + Ohai::Log.debug("Can't load gem: #{e})") +end diff --git a/spec/data/plugins/v6/darwin/uptime.rb b/spec/data/plugins/v6/darwin/uptime.rb new file mode 100644 index 00000000..d9cf01f5 --- /dev/null +++ b/spec/data/plugins/v6/darwin/uptime.rb @@ -0,0 +1,32 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "uptime", "uptime_seconds" + +# kern.boottime: { sec = 1232765114, usec = 823118 } Fri Jan 23 18:45:14 2009 + +popen4("/usr/sbin/sysctl kern.boottime") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /kern.boottime:\D+(\d+)/ + uptime_seconds Time.new.to_i - $1.to_i + uptime self._seconds_to_human(uptime_seconds) + end + end +end + diff --git a/spec/data/plugins/v6/dmi.rb b/spec/data/plugins/v6/dmi.rb new file mode 100644 index 00000000..b892ebcf --- /dev/null +++ b/spec/data/plugins/v6/dmi.rb @@ -0,0 +1,125 @@ +# +# Author:: Kurt Yoder (ktyopscode@yoderhome.com) +# Copyright:: Copyright (c) 2010 Kurt Yoder +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "ohai/plugins/dmi_common" + +provides "dmi" + +# dmidecode does not return data without access to /dev/mem (or its equivalent) + +dmi Mash.new + +# all output lines should fall within one of these patterns +handle_line = /^Handle (0x[0-9A-F]{4}), DMI type (\d+), (\d+) bytes/ +type_line = /^([A-Z][a-zA-Z ]+)( Information)?/ +blank_line = /^\s*$/ +data_line = /^\t([^:]+):(?: (.*))?/ +extended_data_line = /^\t\t(.+)/ +# first lines may contain some interesting information: +# # dmidecode 2.10 +# SMBIOS 2.5 present. +# 5 structures occupying 352 bytes. +# Table at 0x000E1000. +dmidecode_version_line = /^# dmidecode (\d+\.\d+)/ +smbios_version_line = /^SMBIOS (\d+\.\d+) present\./ +structures_line = /^(\d+) structures occupying (\d+) bytes\./ +table_location_line = /^Table at (0x[0-9A-E]+)\./ + +dmi_record = nil +field = nil + +popen4("dmidecode") do |pid, stdin, stdout, stderr| + stdin.close + + # ==== EXAMPLE RECORD: ==== + #Handle 0x0000, DMI type 0, 24 bytes + #BIOS Information + # Vendor: American Megatrends Inc. + # Version: 080012 + # ... similar lines trimmed + # Characteristics: + # ISA is supported + # PCI is supported + # ... similar lines trimmed + stdout.each do |line| + next if blank_line.match(line) + + if dmidecode_version = dmidecode_version_line.match(line) + dmi[:dmidecode_version] = dmidecode_version[1] + + elsif smbios_version = smbios_version_line.match(line) + dmi[:smbios_version] = smbios_version[1] + + elsif structures = structures_line.match(line) + dmi[:structures] = Mash.new + dmi[:structures][:count] = structures[1] + dmi[:structures][:size] = structures[2] + + elsif table_location = table_location_line.match(line) + dmi[:table_location] = table_location[1] + + elsif handle = handle_line.match(line) + # Don't overcapture for now (OHAI-260) + next unless DMI::IdToCapture.include?(handle[2].to_i) + + dmi_record = {:type => DMI.id_lookup(handle[2])} + + dmi[dmi_record[:type]] = Mash.new unless dmi.has_key?(dmi_record[:type]) + dmi[dmi_record[:type]][:all_records] = [] unless dmi[dmi_record[:type]].has_key?(:all_records) + dmi_record[:position] = dmi[dmi_record[:type]][:all_records].length + dmi[dmi_record[:type]][:all_records].push(Mash.new) + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:record_id] = handle[1] + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:size] = handle[2] + field = nil + + elsif type = type_line.match(line) + if dmi_record == nil + Ohai::Log.debug("unexpected data line found before header; discarding:\n#{line}") + next + end + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:application_identifier] = type[1] + + elsif data = data_line.match(line) + if dmi_record == nil + Ohai::Log.debug("unexpected data line found before header; discarding:\n#{line}") + next + end + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][data[1]] = data[2] + field = data[1] + + elsif extended_data = extended_data_line.match(line) + if dmi_record == nil + Ohai::Log.debug("unexpected extended data line found before header; discarding:\n#{line}") + next + end + if field == nil + Ohai::Log.debug("unexpected extended data line found outside data section; discarding:\n#{line}") + next + end + # overwrite "raw" value with a new Mash + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field] = Mash.new unless dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field].class.to_s == 'Mash' + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field][extended_data[1]] = nil + + else + Ohai::Log.debug("unrecognized output line; discarding:\n#{line}") + + end + end +end + +DMI.convenience_keys(dmi) diff --git a/spec/data/plugins/v6/dmi_common.rb b/spec/data/plugins/v6/dmi_common.rb new file mode 100644 index 00000000..8e49ac0e --- /dev/null +++ b/spec/data/plugins/v6/dmi_common.rb @@ -0,0 +1,121 @@ +# +# Author:: Kurt Yoder (ktyopscode@yoderhome.com) +# Copyright:: Copyright (c) 2010 Kurt Yoder +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module DMI + # List of IDs and what they translate to + # from 'man 8 dmidecode' + # all-lowercase, all non-alphanumeric converted to '_' + # 128-255 are 'oem_data_[id]' + # Everything else is 'unknown' + IdToDescription = { + 0 => 'bios', + 1 => 'system', + 2 => 'base_board', + 3 => 'chassis', + 4 => 'processor', + 5 => 'memory_controller', + 6 => 'memory_module', + 7 => 'cache', + 8 => 'port_connector', + 9 => 'system_slots', + 10 => 'on_board_devices', + 11 => 'oem_strings', + 12 => 'system_configuration_options', + 13 => 'bios_language', + 14 => 'group_associations', + 15 => 'system_event_log', + 16 => 'physical_memory_array', + 17 => 'memory_device', + 18 => '32_bit_memory_error', + 19 => 'memory_array_mapped_address', + 20 => 'memory_device_mapped_address', + 21 => 'built_in_pointing_device', + 22 => 'portable_battery', + 23 => 'system_reset', + 24 => 'hardware_security', + 25 => 'system_power_controls', + 26 => 'voltage_probe', + 27 => 'cooling_device', + 28 => 'temperature_probe', + 29 => 'electrical_current_probe', + 30 => 'out_of_band_remote_access', + 31 => 'boot_integrity_services', + 32 => 'system_boot', + 33 => '64_bit_memory_error', + 34 => 'management_device', + 35 => 'management_device_component', + 36 => 'management_device_threshold_data', + 37 => 'memory_channel', + 38 => 'ipmi_device', + 39 => 'power_supply', + 126 => 'disabled_entries', + 127 => 'end_of_table_marker', + } + + # list of IDs to collect, otherwise we generate pages of hashes about cache chip size and whatnot + # See OHAI-260. When we can give the user a choice, this will be a default. + IdToCapture = [ 0, 1, 2, 3, 4, 6, 11 ] + + # look up DMI ID + def DMI.id_lookup(id) + begin + id = id.to_i + if (id >= 128) and (id <= 255) + id = "oem_data_#{id}" + elsif DMI::IdToDescription.has_key?(id) + id = DMI::IdToDescription[id] + else + Ohai::Log.debug("unrecognized header id; falling back to 'unknown'") + id = 'unknown' + end + rescue + Ohai::Log.debug("failed to look up id #{id}, returning unchanged") + id + end + end + + # create simplified convenience access keys for each record type + # for single occurrences of one type, copy to top level all fields and values + # for multiple occurrences of same type, copy to top level all fields and values that are common to all records + def DMI.convenience_keys(dmi) + dmi.each{ |type, records| + in_common = Mash.new + next unless records.class.to_s == 'Mash' + next unless records.has_key?('all_records') + records[:all_records].each{ |record| + record.each{ |field, value| + next if value.class.to_s == 'Mash' + next if field.to_s == 'application_identifier' + next if field.to_s == 'size' + next if field.to_s == 'record_id' + translated = field.downcase.gsub(/[^a-z0-9]/, '_') + if in_common.has_key?(translated) + in_common[translated] = nil unless in_common[translated] == value + else + in_common[translated] = value + end + } + } + in_common.each{ |field, value| + next if value == nil + dmi[type][field] = value + } + } + end + +end diff --git a/spec/data/plugins/v6/ec2.rb b/spec/data/plugins/v6/ec2.rb new file mode 100644 index 00000000..9bede80d --- /dev/null +++ b/spec/data/plugins/v6/ec2.rb @@ -0,0 +1,57 @@ +# +# Author:: Tim Dysinger (<tim@dysinger.net>) +# Author:: Benjamin Black (<bb@opscode.com>) +# Author:: Christopher Brown (<cb@opscode.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provides "ec2" + +require 'ohai/mixin/ec2_metadata' + +require_plugin "hostname" +require_plugin "kernel" +require_plugin "network" + +extend Ohai::Mixin::Ec2Metadata + +def has_ec2_mac? + network[:interfaces].values.each do |iface| + unless iface[:arp].nil? + if iface[:arp].value?("fe:ff:ff:ff:ff:ff") + Ohai::Log.debug("has_ec2_mac? == true") + return true + end + end + end + Ohai::Log.debug("has_ec2_mac? == false") + false +end + +def looks_like_ec2? + # Try non-blocking connect so we don't "block" if + # the Xen environment is *not* EC2 + hint?('ec2') || has_ec2_mac? && can_metadata_connect?(EC2_METADATA_ADDR,80) +end + +if looks_like_ec2? + Ohai::Log.debug("looks_like_ec2? == true") + ec2 Mash.new + fetch_metadata.each {|k, v| ec2[k] = v } + ec2[:userdata] = self.fetch_userdata +else + Ohai::Log.debug("looks_like_ec2? == false") + false +end diff --git a/spec/data/plugins/v6/erlang.rb b/spec/data/plugins/v6/erlang.rb new file mode 100644 index 00000000..db35cde1 --- /dev/null +++ b/spec/data/plugins/v6/erlang.rb @@ -0,0 +1,40 @@ +# +# Author:: Joe Williams (<joe@joetify.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages/erlang" + +require_plugin "languages" + +output = nil + +erlang = Mash.new +status, stdout, stderr = run_command(:no_status_check => true, :command => "erl +V") + +if status == 0 + output = stderr.split + if output.length >= 6 + options = output[1] + options.gsub!(/(\(|\))/, '') + erlang[:version] = output[5] + erlang[:options] = options.split(',') + erlang[:emulator] = output[2].gsub!(/(\(|\))/, '') + if erlang[:version] and erlang[:options] and erlang[:emulator] + languages[:erlang] = erlang + end + end +end diff --git a/spec/data/plugins/v6/eucalyptus.rb b/spec/data/plugins/v6/eucalyptus.rb new file mode 100644 index 00000000..1ee422bc --- /dev/null +++ b/spec/data/plugins/v6/eucalyptus.rb @@ -0,0 +1,65 @@ +# +# Author:: Tim Dysinger (<tim@dysinger.net>) +# Author:: Benjamin Black (<bb@opscode.com>) +# Author:: Christopher Brown (<cb@opscode.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provides "eucalyptus" + +require 'ohai/mixin/ec2_metadata' + +require_plugin "hostname" +require_plugin "kernel" +require_plugin "network" + +extend Ohai::Mixin::Ec2Metadata + +def get_mac_address(addresses) + detected_addresses = addresses.detect { |address, keypair| keypair == {"family"=>"lladdr"} } + if detected_addresses + return detected_addresses.first + else + return "" + end +end + +def has_euca_mac? + network[:interfaces].values.each do |iface| + has_mac = (get_mac_address(iface[:addresses]) =~ /^[dD]0:0[dD]:/) + Ohai::Log.debug("has_euca_mac? == #{!!has_mac}") + return true if has_mac + end + + Ohai::Log.debug("has_euca_mac? == false") + false +end + +def looks_like_euca? + # Try non-blocking connect so we don't "block" if + # the Xen environment is *not* EC2 + hint?('eucalyptus') || has_euca_mac? && can_metadata_connect?(EC2_METADATA_ADDR,80) +end + +if looks_like_euca? + Ohai::Log.debug("looks_like_euca? == true") + eucalyptus Mash.new + self.fetch_metadata.each {|k, v| eucalyptus[k] = v } + eucalyptus[:userdata] = self.fetch_userdata +else + Ohai::Log.debug("looks_like_euca? == false") + false +end + diff --git a/spec/data/plugins/v6/freebsd/cpu.rb b/spec/data/plugins/v6/freebsd/cpu.rb new file mode 100644 index 00000000..d4ae45d4 --- /dev/null +++ b/spec/data/plugins/v6/freebsd/cpu.rb @@ -0,0 +1,52 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2008 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "cpu" + +# all dmesg output for smp I can find only provides info about a single processor +# identical processors is probably a hardware requirement so we'll duplicate data for each cpu +# old examples: http://www.bnv-bamberg.de/home/ba3294/smp/rbuild/index.htm +cpuinfo = Mash.new + +# /var/run/dmesg.boot +#CPU: QEMU Virtual CPU version 0.9.1 (1862.02-MHz 686-class CPU) +# Origin = "GenuineIntel" Id = 0x623 Stepping = 3 +# Features=0x78bfbfd<FPU,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,MMX,FXSR,SSE,SSE2> +# Features2=0x80000001<SSE3,<b31>> + +File.open("/var/run/dmesg.boot").each do |line| + case line + when /CPU:\s+(.+) \(([\d.]+).+\)/ + cpuinfo["model_name"] = $1 + cpuinfo["mhz"] = $2 + when /Origin = "(.+)"\s+Id = (.+)\s+Stepping = (.+)/ + cpuinfo["vendor_id"] = $1 + cpuinfo["stepping"] = $3 + # These _should_ match /AMD Features2?/ lines as well + when /Features=.+<(.+)>/ + cpuinfo["flags"] = $1.downcase.split(',') + # Features2=0x80000001<SSE3,<b31>> + when /Features2=[a-f\dx]+<(.+)>/ + cpuinfo["flags"].concat($1.downcase.split(',')) + when /Logical CPUs per core: (\d+)/ + cpuinfo["cores"] = $1 + end +end + +cpu cpuinfo +cpu[:total] = from("sysctl -n hw.ncpu") diff --git a/spec/data/plugins/v6/freebsd/filesystem.rb b/spec/data/plugins/v6/freebsd/filesystem.rb new file mode 100644 index 00000000..a086b83d --- /dev/null +++ b/spec/data/plugins/v6/freebsd/filesystem.rb @@ -0,0 +1,57 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "filesystem" + +fs = Mash.new + +# Grab filesystem data from df +popen4("df") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^Filesystem/ + next + when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/ + filesystem = $1 + fs[filesystem] = Mash.new + fs[filesystem][:kb_size] = $2 + fs[filesystem][:kb_used] = $3 + fs[filesystem][:kb_available] = $4 + fs[filesystem][:percent_used] = $5 + fs[filesystem][:mount] = $6 + end + end +end + +# Grab mount information from mount +popen4("mount -l") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^(.+?) on (.+?) \((.+?), (.+?)\)$/ + filesystem = $1 + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem][:mount] = $2 + fs[filesystem][:fs_type] = $3 + fs[filesystem][:mount_options] = $4.split(/,\s*/) + end + end +end + +# Set the filesystem data +filesystem fs diff --git a/spec/data/plugins/v6/freebsd/hostname.rb b/spec/data/plugins/v6/freebsd/hostname.rb new file mode 100644 index 00000000..c340dd0c --- /dev/null +++ b/spec/data/plugins/v6/freebsd/hostname.rb @@ -0,0 +1,22 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "hostname", "fqdn" + +hostname from("hostname -s") +fqdn from("hostname -f") diff --git a/spec/data/plugins/v6/freebsd/kernel.rb b/spec/data/plugins/v6/freebsd/kernel.rb new file mode 100644 index 00000000..a0f57240 --- /dev/null +++ b/spec/data/plugins/v6/freebsd/kernel.rb @@ -0,0 +1,37 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "kernel" + +kernel[:os] = kernel[:name] +kernel[:ident] = from("uname -i") +kernel[:securelevel] = from_with_regex("sysctl kern.securelevel", /kern.securelevel: (.+)$/) + +kld = Mash.new +popen4("/sbin/kldstat") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + # 1 7 0xc0400000 97f830 kernel + if line =~ /(\d+)\s+(\d+)\s+([0-9a-fx]+)\s+([0-9a-fx]+)\s+([a-zA-Z0-9\_]+)/ + kld[$5] = { :size => $4, :refcount => $2 } + end + end +end + +kernel[:modules] = kld + diff --git a/spec/data/plugins/v6/freebsd/memory.rb b/spec/data/plugins/v6/freebsd/memory.rb new file mode 100644 index 00000000..f4f3c98c --- /dev/null +++ b/spec/data/plugins/v6/freebsd/memory.rb @@ -0,0 +1,50 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "memory" + +memory Mash.new +memory[:swap] = Mash.new + +# /usr/src/sys/sys/vmmeter.h +memory[:page_size] = from("sysctl -n vm.stats.vm.v_page_size") +memory[:page_count] = from("sysctl -n vm.stats.vm.v_page_count") +memory[:total] = memory[:page_size].to_i * memory[:page_count].to_i +memory[:free] = memory[:page_size].to_i * from("sysctl -n vm.stats.vm.v_free_count").to_i +memory[:active] = memory[:page_size].to_i * from("sysctl -n vm.stats.vm.v_active_count").to_i +memory[:inactive] = memory[:page_size].to_i * from("sysctl -n vm.stats.vm.v_inactive_count").to_i +memory[:cache] = memory[:page_size].to_i * from("sysctl -n vm.stats.vm.v_cache_count").to_i +memory[:wired] = memory[:page_size].to_i * from("sysctl -n vm.stats.vm.v_wire_count").to_i +memory[:buffers] = from("sysctl -n vfs.bufspace") + +popen4("swapinfo") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + # Device 1K-blocks Used Avail Capacity + # /dev/ad0s1b 253648 0 253648 0% + if line =~ /^([\d\w\/]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d\%]+)/ + mdev = $1 + memory[:swap][mdev] = Mash.new + memory[:swap][mdev][:total] = $2 + memory[:swap][mdev][:used] = $3 + memory[:swap][mdev][:free] = $4 + memory[:swap][mdev][:percent_free] = $5 + end + end +end + diff --git a/spec/data/plugins/v6/freebsd/network.rb b/spec/data/plugins/v6/freebsd/network.rb new file mode 100644 index 00000000..a76f57d0 --- /dev/null +++ b/spec/data/plugins/v6/freebsd/network.rb @@ -0,0 +1,121 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "network", "counters/network" + +from("route -n get default").split("\n").each do |line| + if line =~ /(\w+): ([\w\.]+)/ + case $1 + when "gateway" + network[:default_gateway] = $2 + when "interface" + network[:default_interface] = $2 + end + end +end + +iface = Mash.new +popen4("/sbin/ifconfig -a") do |pid, stdin, stdout, stderr| + stdin.close + cint = nil + stdout.each do |line| + if line =~ /^([0-9a-zA-Z\.]+):\s+/ + cint = $1 + iface[cint] = Mash.new + if cint =~ /^(\w+)(\d+.*)/ + iface[cint][:type] = $1 + iface[cint][:number] = $2 + end + end + # call the family lladdr to match linux for consistency + if line =~ /\s+ether (.+?)\s/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "lladdr" } + end + if line =~ /\s+inet ([\d.]+) netmask ([\da-fx]+)\s*\w*\s*([\d.]*)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + # convert the netmask to decimal for consistency + netmask = "#{$2[2,2].hex}.#{$2[4,2].hex}.#{$2[6,2].hex}.#{$2[8,2].hex}" + if $3.empty? + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask } + else + # found a broadcast address + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask, "broadcast" => $3 } + end + end + if line =~ /\s+inet6 ([a-f0-9\:]+)%?(\w*)\s+prefixlen\s+(\d+)\s*\w*\s*([\da-fx]*)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + if $4.empty? + iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $3 } + else + # found a zone_id / scope + iface[cint][:addresses][$1] = { "family" => "inet6", "zoneid" => $2, "prefixlen" => $3, "scopeid" => $4 } + end + end + if line =~ /flags=\d+<(.+)>/ + flags = $1.split(',') + iface[cint][:flags] = flags if flags.length > 0 + end + if line =~ /metric: (\d+) mtu: (\d+)/ + iface[cint][:metric] = $1 + iface[cint][:mtu] = $2 + end + end +end + +popen4("arp -an") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) on ([0-9a-zA-Z\.\:\-]+)/ + next unless iface[$3] # this should never happen + iface[$3][:arp] = Mash.new unless iface[$3][:arp] + iface[$3][:arp][$1] = $2.downcase + end + end +end + +network["interfaces"] = iface + +net_counters = Mash.new +# From netstat(1), not sure of the implications: +# Show the state of all network interfaces or a single interface +# which have been auto-configured (interfaces statically configured +# into a system, but not located at boot time are not shown). +popen4("netstat -ibdn") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + # Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop + # ed0 1500 <Link#1> 54:52:00:68:92:85 333604 26 151905886 175472 0 24897542 0 905 + # $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 + if line =~ /^([\w\.\*]+)\s+\d+\s+<Link#\d+>\s+([\w:]*)\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ + net_counters[$1] = Mash.new unless net_counters[$1] + net_counters[$1]["rx"] = Mash.new unless net_counters[$1]["rx"] + net_counters[$1]["tx"] = Mash.new unless net_counters[$1]["tx"] + net_counters[$1]["rx"]["packets"] = $3 + net_counters[$1]["rx"]["errors"] = $4 + net_counters[$1]["rx"]["bytes"] = $5 + net_counters[$1]["tx"]["packets"] = $6 + net_counters[$1]["tx"]["errors"] = $7 + net_counters[$1]["tx"]["bytes"] = $8 + net_counters[$1]["tx"]["collisions"] = $9 + net_counters[$1]["tx"]["dropped"] = $10 + end + end +end + +counters[:network][:interfaces] = net_counters diff --git a/spec/data/plugins/v6/freebsd/platform.rb b/spec/data/plugins/v6/freebsd/platform.rb new file mode 100644 index 00000000..78697e72 --- /dev/null +++ b/spec/data/plugins/v6/freebsd/platform.rb @@ -0,0 +1,23 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "platform", "platform_version" + +platform from("uname -s").downcase +platform_version from("uname -r") + diff --git a/spec/data/plugins/v6/freebsd/ps.rb b/spec/data/plugins/v6/freebsd/ps.rb new file mode 100644 index 00000000..f4823327 --- /dev/null +++ b/spec/data/plugins/v6/freebsd/ps.rb @@ -0,0 +1,24 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "command/ps" + +require_plugin 'command' + +# ps -e requires procfs +command[:ps] = 'ps -ax' diff --git a/spec/data/plugins/v6/freebsd/uptime.rb b/spec/data/plugins/v6/freebsd/uptime.rb new file mode 100644 index 00000000..7d0da153 --- /dev/null +++ b/spec/data/plugins/v6/freebsd/uptime.rb @@ -0,0 +1,32 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "uptime", "uptime_seconds" + +# kern.boottime: { sec = 1232765114, usec = 823118 } Fri Jan 23 18:45:14 2009 + +popen4("/sbin/sysctl kern.boottime") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /kern.boottime:\D+(\d+)/ + uptime_seconds Time.new.to_i - $1.to_i + uptime self._seconds_to_human(uptime_seconds) + end + end +end + diff --git a/spec/data/plugins/v6/freebsd/virtualization.rb b/spec/data/plugins/v6/freebsd/virtualization.rb new file mode 100644 index 00000000..96ee6fab --- /dev/null +++ b/spec/data/plugins/v6/freebsd/virtualization.rb @@ -0,0 +1,93 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "virtualization" + +virtualization Mash.new + +if from("sysctl -n security.jail.jailed").to_i == 1 + virtualization[:system] = "jail" + virtualization[:role] = "guest" +end + +# detect from modules +popen4("/sbin/kldstat") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /vboxdrv/ + virtualization[:system] = "vbox" + virtualization[:role] = "host" + when /vboxguest/ + virtualization[:system] = "vbox" + virtualization[:role] = "guest" + end + end +end + + +# XXX doesn't work when jail is there but not running (ezjail-admin stop) +if from("jls -n \| wc -l").to_i >= 1 + virtualization[:system] = "jail" + virtualization[:role] = "host" +end + +# KVM Host support for FreeBSD is in development +# http://feanor.sssup.it/~fabio/freebsd/lkvm/ + +# Detect KVM/QEMU from cpu, report as KVM +# hw.model: QEMU Virtual CPU version 0.9.1 +if from("sysctl -n hw.model") =~ /QEMU Virtual CPU/ + virtualization[:system] = "kvm" + virtualization[:role] = "guest" +end + +# http://www.dmo.ca/blog/detecting-virtualization-on-linux +if File.exists?("/usr/local/sbin/dmidecode") + popen4("dmidecode") do |pid, stdin, stdout, stderr| + stdin.close + found_virt_manufacturer = nil + found_virt_product = nil + stdout.each do |line| + case line + when /Manufacturer: Microsoft/ + found_virt_manufacturer = "microsoft" + when /Product Name: Virtual Machine/ + found_virt_product = "microsoft" + when /Version: 5.0/ + if found_virt_manufacturer == "microsoft" && found_virt_product == "microsoft" + virtualization[:system] = "virtualpc" + virtualization[:role] = "guest" + end + when /Version: VS2005R2/ + if found_virt_manufacturer == "microsoft" && found_virt_product == "microsoft" + virtualization[:system] = "virtualserver" + virtualization[:role] = "guest" + end + when /Manufacturer: VMware/ + found_virt_manufacturer = "vmware" + when /Product Name: VMware Virtual Platform/ + if found_virt_manufacturer == "vmware" + virtualization[:system] = "vmware" + virtualization[:role] = "guest" + end + end + end + end +end + diff --git a/spec/data/plugins/v6/gce.rb b/spec/data/plugins/v6/gce.rb new file mode 100644 index 00000000..de5b0b4f --- /dev/null +++ b/spec/data/plugins/v6/gce.rb @@ -0,0 +1,40 @@ +# +# Author:: Ranjib Dey (<dey.ranjib@google.com>) +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provides "gce" + +require 'ohai/mixin/gce_metadata' + + +GOOGLE_SYSFS_DMI = '/sys/firmware/dmi/entries/1-0/raw' + +#https://developers.google.com/compute/docs/instances#dmi +def has_google_dmi? + ::File.read(GOOGLE_SYSFS_DMI).include?('Google') +end + +def looks_like_gce? + hint?('gce') || (has_google_dmi? && Ohai::Mixin::GCEMetadata.can_metadata_connect?(Ohai::Mixin::GCEMetadata::GCE_METADATA_ADDR,80)) +end + +if looks_like_gce? + Ohai::Log.debug("looks_like_gce? == true") + gce Mash.new + Ohai::Mixin::GCEMetadata.fetch_metadata.each {|k, v| gce[k] = v } +else + Ohai::Log.debug("looks_like_gce? == false") + false +end diff --git a/spec/data/plugins/v6/groovy.rb b/spec/data/plugins/v6/groovy.rb new file mode 100644 index 00000000..8979a563 --- /dev/null +++ b/spec/data/plugins/v6/groovy.rb @@ -0,0 +1,35 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2009 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages/groovy" + +require_plugin "languages" + +output = nil + +groovy = Mash.new + +status, stdout, stderr = run_command(:no_status_check => true, :command => "groovy -v") +if status == 0 + output = stdout.split + if output.length >= 2 + groovy[:version] = output[2] + end + languages[:groovy] = groovy if groovy[:version] +end + diff --git a/spec/data/plugins/v6/hostname.rb b/spec/data/plugins/v6/hostname.rb new file mode 100644 index 00000000..119e3c29 --- /dev/null +++ b/spec/data/plugins/v6/hostname.rb @@ -0,0 +1,27 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "fqdn", "domain" + +require_plugin "#{os}::hostname" + +# Domain is everything after the first dot +if fqdn + fqdn =~ /.+?\.(.*)/ + domain $1 +end
\ No newline at end of file diff --git a/spec/data/plugins/v6/hpux/cpu.rb b/spec/data/plugins/v6/hpux/cpu.rb new file mode 100644 index 00000000..32b2dc91 --- /dev/null +++ b/spec/data/plugins/v6/hpux/cpu.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::cpu" diff --git a/spec/data/plugins/v6/hpux/filesystem.rb b/spec/data/plugins/v6/hpux/filesystem.rb new file mode 100644 index 00000000..8322ee0b --- /dev/null +++ b/spec/data/plugins/v6/hpux/filesystem.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::filesystem" diff --git a/spec/data/plugins/v6/hpux/hostname.rb b/spec/data/plugins/v6/hpux/hostname.rb new file mode 100644 index 00000000..805b4734 --- /dev/null +++ b/spec/data/plugins/v6/hpux/hostname.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::hostname" diff --git a/spec/data/plugins/v6/hpux/memory.rb b/spec/data/plugins/v6/hpux/memory.rb new file mode 100644 index 00000000..dd3532fb --- /dev/null +++ b/spec/data/plugins/v6/hpux/memory.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::memory" diff --git a/spec/data/plugins/v6/hpux/network.rb b/spec/data/plugins/v6/hpux/network.rb new file mode 100644 index 00000000..7071abef --- /dev/null +++ b/spec/data/plugins/v6/hpux/network.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::network" diff --git a/spec/data/plugins/v6/hpux/platform.rb b/spec/data/plugins/v6/hpux/platform.rb new file mode 100644 index 00000000..bea329d6 --- /dev/null +++ b/spec/data/plugins/v6/hpux/platform.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::platform" diff --git a/spec/data/plugins/v6/hpux/ps.rb b/spec/data/plugins/v6/hpux/ps.rb new file mode 100644 index 00000000..9532014a --- /dev/null +++ b/spec/data/plugins/v6/hpux/ps.rb @@ -0,0 +1,23 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "command/ps" + +require_plugin 'command' + +command[:ps] = 'ps -ef' diff --git a/spec/data/plugins/v6/hpux/uptime.rb b/spec/data/plugins/v6/hpux/uptime.rb new file mode 100644 index 00000000..23aa89f3 --- /dev/null +++ b/spec/data/plugins/v6/hpux/uptime.rb @@ -0,0 +1,19 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "sigar::uptime" diff --git a/spec/data/plugins/v6/ip_scopes.rb b/spec/data/plugins/v6/ip_scopes.rb new file mode 100644 index 00000000..0b0f377e --- /dev/null +++ b/spec/data/plugins/v6/ip_scopes.rb @@ -0,0 +1,42 @@ +# +# Author:: James Harton (<james@sociable.co.nz>) +# Copyright:: Copyright (c) 2010 Sociable Limited. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +begin + require 'ipaddr_extensions' + + provides "network_ip_scope", "privateaddress" + + require_plugin "hostname" + require_plugin "network" + + network['interfaces'].keys.each do |ifName| + next if network['interfaces'][ifName]['addresses'].nil? + + network['interfaces'][ifName]['addresses'].each do |address,attrs| + begin + attrs.merge! 'ip_scope' => address.to_ip.scope + privateaddress address if address.to_ip.scope =~ /PRIVATE/ + rescue ArgumentError + # Just silently fail if we can't create an IP from the string. + end + end + end + +rescue LoadError => e + # our favourite gem is not installed. Boohoo. + Ohai::Log.debug("ip_scopes: cannot load gem, plugin disabled: #{e}") +end diff --git a/spec/data/plugins/v6/java.rb b/spec/data/plugins/v6/java.rb new file mode 100644 index 00000000..67310bfd --- /dev/null +++ b/spec/data/plugins/v6/java.rb @@ -0,0 +1,46 @@ +# +# Author:: Benjamin Black (<bb@opscode.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +provides "languages/java" + +require_plugin "languages" + +java = Mash.new + +status, stdout, stderr = nil +if RUBY_PLATFORM.downcase.include?("darwin") + if system("/usr/libexec/java_home 2>&1 >/dev/null") + status, stdout, stderr = run_command(:no_status_check => true, :command => "java -version") + end +else + status, stdout, stderr = run_command(:no_status_check => true, :command => "java -version") +end + +if status == 0 + stderr.split("\n").each do |line| + case line + when /java version \"([0-9\.\_]+)\"/ + java[:version] = $1 + when /^(.+Runtime Environment.*) \((build )?(.+)\)$/ + java[:runtime] = { "name" => $1, "build" => $3 } + when /^(.+ (Client|Server) VM) \(build (.+)\)$/ + java[:hotspot] = { "name" => $1, "build" => $3 } + end + end + + languages[:java] = java if java[:version] +end diff --git a/spec/data/plugins/v6/kernel.rb b/spec/data/plugins/v6/kernel.rb new file mode 100644 index 00000000..d50b3876 --- /dev/null +++ b/spec/data/plugins/v6/kernel.rb @@ -0,0 +1,34 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "kernel" + +require_plugin 'ruby' + +kernel Mash.new +case languages[:ruby][:host_os] +when /mswin|mingw32|windows/ + require_plugin "windows::kernel" + require_plugin "windows::kernel_devices" +else + kernel[:name] = from("uname -s") + kernel[:release] = from("uname -r") + kernel[:version] = from("uname -v") + kernel[:machine] = from("uname -m") + kernel[:modules] = Mash.new +end diff --git a/spec/data/plugins/v6/keys.rb b/spec/data/plugins/v6/keys.rb new file mode 100644 index 00000000..99709f7a --- /dev/null +++ b/spec/data/plugins/v6/keys.rb @@ -0,0 +1,22 @@ +# +# Cookbook Name:: apache2 +# Recipe:: default +# +# Copyright 2008, OpsCode, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "keys" + +keys Mash.new
\ No newline at end of file diff --git a/spec/data/plugins/v6/languages.rb b/spec/data/plugins/v6/languages.rb new file mode 100644 index 00000000..9dbd2f43 --- /dev/null +++ b/spec/data/plugins/v6/languages.rb @@ -0,0 +1,21 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages" + +languages Mash.new diff --git a/spec/data/plugins/v6/linode.rb b/spec/data/plugins/v6/linode.rb new file mode 100644 index 00000000..69613857 --- /dev/null +++ b/spec/data/plugins/v6/linode.rb @@ -0,0 +1,53 @@ +# +# Author:: Aaron Kalin (<akalin@martinisoftware.com>) +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provides "linode" + +require_plugin "kernel" +require_plugin "network" + +# Checks for matching linode kernel name +# +# Returns true or false +def has_linode_kernel? + kernel[:release].split('-').last =~ /linode/ +end + +# Identifies the linode cloud by preferring the hint, then +# +# Returns true or false +def looks_like_linode? + hint?('linode') || has_linode_kernel? +end + +# Names linode ip address +# +# name - symbol of ohai name (e.g. :public_ip) +# eth - Interface name (e.g. :eth0) +# +# Alters linode mash with new interface based on name parameter +def get_ip_address(name, eth) + network[:interfaces][eth][:addresses].each do |key, info| + linode[name] = key if info['family'] == 'inet' + end +end + +# Setup linode mash if it is a linode system +if looks_like_linode? + linode Mash.new + get_ip_address(:public_ip, :eth0) + get_ip_address(:private_ip, "eth0:1") +end diff --git a/spec/data/plugins/v6/linux/block_device.rb b/spec/data/plugins/v6/linux/block_device.rb new file mode 100644 index 00000000..2fee4b68 --- /dev/null +++ b/spec/data/plugins/v6/linux/block_device.rb @@ -0,0 +1,38 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "block_device" + +if File.exists?("/sys/block") + block = Mash.new + Dir["/sys/block/*"].each do |block_device_dir| + dir = File.basename(block_device_dir) + block[dir] = Mash.new + %w{size removable}.each do |check| + if File.exists?("/sys/block/#{dir}/#{check}") + File.open("/sys/block/#{dir}/#{check}") { |f| block[dir][check] = f.read_nonblock(1024).strip } + end + end + %w{model rev state timeout vendor}.each do |check| + if File.exists?("/sys/block/#{dir}/device/#{check}") + File.open("/sys/block/#{dir}/device/#{check}") { |f| block[dir][check] = f.read_nonblock(1024).strip } + end + end + end + block_device block +end diff --git a/spec/data/plugins/v6/linux/cpu.rb b/spec/data/plugins/v6/linux/cpu.rb new file mode 100644 index 00000000..48468a5e --- /dev/null +++ b/spec/data/plugins/v6/linux/cpu.rb @@ -0,0 +1,60 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "cpu" + +cpuinfo = Mash.new +real_cpu = Mash.new +cpu_number = 0 +current_cpu = nil + +File.open("/proc/cpuinfo").each do |line| + case line + when /processor\s+:\s(.+)/ + cpuinfo[$1] = Mash.new + current_cpu = $1 + cpu_number += 1 + when /vendor_id\s+:\s(.+)/ + cpuinfo[current_cpu]["vendor_id"] = $1 + when /cpu family\s+:\s(.+)/ + cpuinfo[current_cpu]["family"] = $1 + when /model\s+:\s(.+)/ + cpuinfo[current_cpu]["model"] = $1 + when /stepping\s+:\s(.+)/ + cpuinfo[current_cpu]["stepping"] = $1 + when /physical id\s+:\s(.+)/ + cpuinfo[current_cpu]["physical_id"] = $1 + real_cpu[$1] = true + when /core id\s+:\s(.+)/ + cpuinfo[current_cpu]["core_id"] = $1 + when /cpu cores\s+:\s(.+)/ + cpuinfo[current_cpu]["cores"] = $1 + when /model name\s+:\s(.+)/ + cpuinfo[current_cpu]["model_name"] = $1 + when /cpu MHz\s+:\s(.+)/ + cpuinfo[current_cpu]["mhz"] = $1 + when /cache size\s+:\s(.+)/ + cpuinfo[current_cpu]["cache_size"] = $1 + when /flags\s+:\s(.+)/ + cpuinfo[current_cpu]["flags"] = $1.split(' ') + end +end + +cpu cpuinfo +cpu[:total] = cpu_number +cpu[:real] = real_cpu.keys.length
\ No newline at end of file diff --git a/spec/data/plugins/v6/linux/filesystem.rb b/spec/data/plugins/v6/linux/filesystem.rb new file mode 100644 index 00000000..2076d0b5 --- /dev/null +++ b/spec/data/plugins/v6/linux/filesystem.rb @@ -0,0 +1,107 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "filesystem" + +fs = Mash.new + +# Grab filesystem data from df +popen4("df -P") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^Filesystem\s+1024-blocks/ + next + when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/ + filesystem = $1 + fs[filesystem] = Mash.new + fs[filesystem][:kb_size] = $2 + fs[filesystem][:kb_used] = $3 + fs[filesystem][:kb_available] = $4 + fs[filesystem][:percent_used] = $5 + fs[filesystem][:mount] = $6 + end + end +end + +# Grab mount information from /bin/mount +popen4("mount") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^(.+?) on (.+?) type (.+?) \((.+?)\)$/ + filesystem = $1 + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem][:mount] = $2 + fs[filesystem][:fs_type] = $3 + fs[filesystem][:mount_options] = $4.split(",") + end + end +end + +# Gather more filesystem types via libuuid, even devices that's aren't mounted +popen4("blkid -s TYPE") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^(\S+): TYPE="(\S+)"/ + filesystem = $1 + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem][:fs_type] = $2 + end + end +end + +# Gather device UUIDs via libuuid +popen4("blkid -s UUID") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^(\S+): UUID="(\S+)"/ + filesystem = $1 + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem][:uuid] = $2 + end + end +end + +# Gather device labels via libuuid +popen4("blkid -s LABEL") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^(\S+): LABEL="(\S+)"/ + filesystem = $1 + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem][:label] = $2 + end + end +end + +# Grab any missing mount information from /proc/mounts +if File.exists?('/proc/mounts') + File.open('/proc/mounts').read_nonblock(4096).each_line do |line| + if line =~ /^(\S+) (\S+) (\S+) (\S+) \S+ \S+$/ + filesystem = $1 + next if fs.has_key?(filesystem) + fs[filesystem] = Mash.new + fs[filesystem][:mount] = $2 + fs[filesystem][:fs_type] = $3 + fs[filesystem][:mount_options] = $4.split(",") + end + end +end + +# Set the filesystem data +filesystem fs diff --git a/spec/data/plugins/v6/linux/hostname.rb b/spec/data/plugins/v6/linux/hostname.rb new file mode 100644 index 00000000..896ad821 --- /dev/null +++ b/spec/data/plugins/v6/linux/hostname.rb @@ -0,0 +1,26 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "hostname", "fqdn" + +hostname from("hostname -s") +begin + fqdn from("hostname --fqdn") +rescue + Ohai::Log.debug("hostname -f returned an error, probably no domain is set") +end diff --git a/spec/data/plugins/v6/linux/kernel.rb b/spec/data/plugins/v6/linux/kernel.rb new file mode 100644 index 00000000..c862688a --- /dev/null +++ b/spec/data/plugins/v6/linux/kernel.rb @@ -0,0 +1,33 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "kernel" + +kernel[:os] = from("uname -o") + +kext = Mash.new +popen4("env lsmod") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /([a-zA-Z0-9\_]+)\s+(\d+)\s+(\d+)/ + kext[$1] = { :size => $2, :refcount => $3 } + end + end +end + +kernel[:modules] = kext diff --git a/spec/data/plugins/v6/linux/lsb.rb b/spec/data/plugins/v6/linux/lsb.rb new file mode 100644 index 00000000..9750c20a --- /dev/null +++ b/spec/data/plugins/v6/linux/lsb.rb @@ -0,0 +1,59 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "lsb" + +lsb Mash.new + +if File.exists?("/etc/lsb-release") + File.open("/etc/lsb-release").each do |line| + case line + when /^DISTRIB_ID=["']?(.+?)["']?$/ + lsb[:id] = $1 + when /^DISTRIB_RELEASE=["']?(.+?)["']?$/ + lsb[:release] = $1 + when /^DISTRIB_CODENAME=["']?(.+?)["']?$/ + lsb[:codename] = $1 + when /^DISTRIB_DESCRIPTION=["']?(.+?)["']?$/ + lsb[:description] = $1 + end + end +elsif File.exists?("/usr/bin/lsb_release") + # Fedora/Redhat, requires redhat-lsb package + popen4("lsb_release -a") do |pid, stdin, stdout, stderr| + + stdin.close + stdout.each do |line| + case line + when /^Distributor ID:\s+(.+)$/ + lsb[:id] = $1 + when /^Description:\s+(.+)$/ + lsb[:description] = $1 + when /^Release:\s+(.+)$/ + lsb[:release] = $1 + when /^Codename:\s+(.+)$/ + lsb[:codename] = $1 + else + lsb[:id] = line + end + + end + end +else + Ohai::Log.debug("Skipping LSB, cannot find /etc/lsb-release or /usr/bin/lsb_release") +end diff --git a/spec/data/plugins/v6/linux/memory.rb b/spec/data/plugins/v6/linux/memory.rb new file mode 100644 index 00000000..51ec2099 --- /dev/null +++ b/spec/data/plugins/v6/linux/memory.rb @@ -0,0 +1,83 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "memory" + +memory Mash.new +memory[:swap] = Mash.new + +File.open("/proc/meminfo").each do |line| + case line + when /^MemTotal:\s+(\d+) (.+)$/ + memory[:total] = "#{$1}#{$2}" + when /^MemFree:\s+(\d+) (.+)$/ + memory[:free] = "#{$1}#{$2}" + when /^Buffers:\s+(\d+) (.+)$/ + memory[:buffers] = "#{$1}#{$2}" + when /^Cached:\s+(\d+) (.+)$/ + memory[:cached] = "#{$1}#{$2}" + when /^Active:\s+(\d+) (.+)$/ + memory[:active] = "#{$1}#{$2}" + when /^Inactive:\s+(\d+) (.+)$/ + memory[:inactive] = "#{$1}#{$2}" + when /^HighTotal:\s+(\d+) (.+)$/ + memory[:high_total] = "#{$1}#{$2}" + when /^HighFree:\s+(\d+) (.+)$/ + memory[:high_free] = "#{$1}#{$2}" + when /^LowTotal:\s+(\d+) (.+)$/ + memory[:low_total] = "#{$1}#{$2}" + when /^LowFree:\s+(\d+) (.+)$/ + memory[:low_free] = "#{$1}#{$2}" + when /^Dirty:\s+(\d+) (.+)$/ + memory[:dirty] = "#{$1}#{$2}" + when /^Writeback:\s+(\d+) (.+)$/ + memory[:writeback] = "#{$1}#{$2}" + when /^AnonPages:\s+(\d+) (.+)$/ + memory[:anon_pages] = "#{$1}#{$2}" + when /^Mapped:\s+(\d+) (.+)$/ + memory[:mapped] = "#{$1}#{$2}" + when /^Slab:\s+(\d+) (.+)$/ + memory[:slab] = "#{$1}#{$2}" + when /^SReclaimable:\s+(\d+) (.+)$/ + memory[:slab_reclaimable] = "#{$1}#{$2}" + when /^SUnreclaim:\s+(\d+) (.+)$/ + memory[:slab_unreclaim] = "#{$1}#{$2}" + when /^PageTables:\s+(\d+) (.+)$/ + memory[:page_tables] = "#{$1}#{$2}" + when /^NFS_Unstable:\s+(\d+) (.+)$/ + memory[:nfs_unstable] = "#{$1}#{$2}" + when /^Bounce:\s+(\d+) (.+)$/ + memory[:bounce] = "#{$1}#{$2}" + when /^CommitLimit:\s+(\d+) (.+)$/ + memory[:commit_limit] = "#{$1}#{$2}" + when /^Committed_AS:\s+(\d+) (.+)$/ + memory[:committed_as] = "#{$1}#{$2}" + when /^VmallocTotal:\s+(\d+) (.+)$/ + memory[:vmalloc_total] = "#{$1}#{$2}" + when /^VmallocUsed:\s+(\d+) (.+)$/ + memory[:vmalloc_used] = "#{$1}#{$2}" + when /^VmallocChunk:\s+(\d+) (.+)$/ + memory[:vmalloc_chunk] = "#{$1}#{$2}" + when /^SwapCached:\s+(\d+) (.+)$/ + memory[:swap][:cached] = "#{$1}#{$2}" + when /^SwapTotal:\s+(\d+) (.+)$/ + memory[:swap][:total] = "#{$1}#{$2}" + when /^SwapFree:\s+(\d+) (.+)$/ + memory[:swap][:free] = "#{$1}#{$2}" + end +end diff --git a/spec/data/plugins/v6/linux/network.rb b/spec/data/plugins/v6/linux/network.rb new file mode 100644 index 00000000..9f6891d4 --- /dev/null +++ b/spec/data/plugins/v6/linux/network.rb @@ -0,0 +1,412 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'ipaddr' +provides "network", "counters/network" + +def encaps_lookup(encap) + return "Loopback" if encap.eql?("Local Loopback") || encap.eql?("loopback") + return "PPP" if encap.eql?("Point-to-Point Protocol") + return "SLIP" if encap.eql?("Serial Line IP") + return "VJSLIP" if encap.eql?("VJ Serial Line IP") + return "IPIP" if encap.eql?("IPIP Tunnel") + return "6to4" if encap.eql?("IPv6-in-IPv4") + return "Ethernet" if encap.eql?("ether") + encap +end + +iface = Mash.new +net_counters = Mash.new + +# Match the lead line for an interface from iproute2 +# 3: eth0.11@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP +# The '@eth0:' portion doesn't exist on primary interfaces and thus is optional in the regex +IPROUTE_INT_REGEX = /^(\d+): ([0-9a-zA-Z@:\.\-_]*?)(@[0-9a-zA-Z]+|):\s/ + +if File.exist?("/sbin/ip") + + # families to get default routes from + families = [ + { + :name => "inet", + :default_route => "0.0.0.0/0", + :default_prefix => :default, + :neighbour_attribute => :arp + }, + { + :name => "inet6", + :default_route => "::/0", + :default_prefix => :default_inet6, + :neighbour_attribute => :neighbour_inet6 + } + ] + + popen4("ip addr") do |pid, stdin, stdout, stderr| + stdin.close + cint = nil + stdout.each do |line| + if line =~ IPROUTE_INT_REGEX + cint = $2 + iface[cint] = Mash.new + if cint =~ /^(\w+)(\d+.*)/ + iface[cint][:type] = $1 + iface[cint][:number] = $2 + end + + if line =~ /mtu (\d+)/ + iface[cint][:mtu] = $1 + end + + flags = line.scan(/(UP|BROADCAST|DEBUG|LOOPBACK|POINTTOPOINT|NOTRAILERS|LOWER_UP|NOARP|PROMISC|ALLMULTI|SLAVE|MASTER|MULTICAST|DYNAMIC)/) + if flags.length > 1 + iface[cint][:flags] = flags.flatten.uniq + end + end + if line =~ /link\/(\w+) ([\da-f\:]+) / + iface[cint][:encapsulation] = encaps_lookup($1) + unless $2 == "00:00:00:00:00:00" + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$2.upcase] = { "family" => "lladdr" } + end + end + if line =~ /inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(\/(\d{1,2}))?/ + tmp_addr, tmp_prefix = $1, $3 + tmp_prefix ||= "32" + original_int = nil + + # Are we a formerly aliased interface? + if line =~ /#{cint}:(\d+)$/ + sub_int = $1 + alias_int = "#{cint}:#{sub_int}" + original_int = cint + cint = alias_int + end + + iface[cint] = Mash.new unless iface[cint] # Create the fake alias interface if needed + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][tmp_addr] = { "family" => "inet", "prefixlen" => tmp_prefix } + iface[cint][:addresses][tmp_addr][:netmask] = IPAddr.new("255.255.255.255").mask(tmp_prefix.to_i).to_s + + if line =~ /peer (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ + iface[cint][:addresses][tmp_addr][:peer] = $1 + end + + if line =~ /brd (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ + iface[cint][:addresses][tmp_addr][:broadcast] = $1 + end + + if line =~ /scope (\w+)/ + iface[cint][:addresses][tmp_addr][:scope] = ($1.eql?("host") ? "Node" : $1.capitalize) + end + + # If we found we were an an alias interface, restore cint to its original value + cint = original_int unless original_int.nil? + end + if line =~ /inet6 ([a-f0-9\:]+)\/(\d+) scope (\w+)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + tmp_addr = $1 + iface[cint][:addresses][tmp_addr] = { "family" => "inet6", "prefixlen" => $2, "scope" => ($3.eql?("host") ? "Node" : $3.capitalize) } + end + end + end + + popen4("ip -d -s link") do |pid, stdin, stdout, stderr| + stdin.close + tmp_int = nil + on_rx = true + stdout.each do |line| + if line =~ IPROUTE_INT_REGEX + tmp_int = $2 + net_counters[tmp_int] = Mash.new unless net_counters[tmp_int] + end + + if line =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ + int = on_rx ? :rx : :tx + net_counters[tmp_int][int] = Mash.new unless net_counters[tmp_int][int] + net_counters[tmp_int][int][:bytes] = $1 + net_counters[tmp_int][int][:packets] = $2 + net_counters[tmp_int][int][:errors] = $3 + net_counters[tmp_int][int][:drop] = $4 + if(int == :rx) + net_counters[tmp_int][int][:overrun] = $5 + else + net_counters[tmp_int][int][:carrier] = $5 + net_counters[tmp_int][int][:collisions] = $6 + end + + on_rx = !on_rx + end + + if line =~ /qlen (\d+)/ + net_counters[tmp_int][:tx] = Mash.new unless net_counters[tmp_int][:tx] + net_counters[tmp_int][:tx][:queuelen] = $1 + end + + if line =~ /vlan id (\d+)/ + tmp_id = $1 + iface[tmp_int][:vlan] = Mash.new unless iface[tmp_int][:vlan] + iface[tmp_int][:vlan][:id] = tmp_id + + vlan_flags = line.scan(/(REORDER_HDR|GVRP|LOOSE_BINDING)/) + if vlan_flags.length > 0 + iface[tmp_int][:vlan][:flags] = vlan_flags.flatten.uniq + end + end + + if line =~ /state (\w+)/ + iface[tmp_int]['state'] = $1.downcase + end + + + end + end + + families.each do |family| + neigh_attr = family[:neighbour_attribute] + default_prefix = family[:default_prefix] + + popen4("ip -f #{family[:name]} neigh show") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^([a-f0-9\:\.]+)\s+dev\s+([^\s]+)\s+lladdr\s+([a-fA-F0-9\:]+)/ + unless iface[$2] + Ohai::Log.warn("neighbour list has entries for unknown interface #{iface[$2]}") + next + end + iface[$2][neigh_attr] = Mash.new unless iface[$2][neigh_attr] + iface[$2][neigh_attr][$1] = $3.downcase + end + end + end + + # checking the routing tables + # why ? + # 1) to set the default gateway and default interfaces attributes + # 2) on some occasions, the best way to select node[:ipaddress] is to look at + # the routing table source field. + # 3) and since we're at it, let's populate some :routes attributes + # (going to do that for both inet and inet6 addresses) + popen4("ip -f #{family[:name]} route show") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^([^\s]+)\s(.*)$/ + route_dest = $1 + route_ending = $2 + # + if route_ending =~ /\bdev\s+([^\s]+)\b/ + route_int = $1 + else + Ohai::Log.debug("Skipping route entry without a device: '#{line}'") + next + end + + unless iface[route_int] + Ohai::Log.debug("Skipping previously unseen interface from 'ip route show': #{route_int}") + next + end + + route_entry = Mash.new( :destination => route_dest, + :family => family[:name] ) + %w[via scope metric proto src].each do |k| + route_entry[k] = $1 if route_ending =~ /\b#{k}\s+([^\s]+)\b/ + end + + # a sanity check, especially for Linux-VServer, OpenVZ and LXC: + # don't report the route entry if the src address isn't set on the node + next if route_entry[:src] and not iface[route_int][:addresses].has_key? route_entry[:src] + + iface[route_int][:routes] = Array.new unless iface[route_int][:routes] + iface[route_int][:routes] << route_entry + end + end + end + # now looking at the routes to set the default attributes + # for information, default routes can be of this form : + # - default via 10.0.2.4 dev br0 + # - default dev br0 scope link + # - default via 10.0.3.1 dev eth1 src 10.0.3.2 metric 10 + # - default via 10.0.4.1 dev eth2 src 10.0.4.2 metric 20 + + # using a temporary var to hold routes and their interface name + routes = iface.collect do |i,iv| + iv[:routes].collect do |r| + r.merge(:dev=>i) if r[:family] == family[:name] + end.compact if iv[:routes] + end.compact.flatten + + # using a temporary var to hold the default route + # in case there are more than 1 default route, sort it by its metric + # and return the first one + # (metric value when unspecified is 0) + default_route = routes.select do |r| + r[:destination] == "default" + end.sort do |x,y| + (x[:metric].nil? ? 0 : x[:metric].to_i) <=> (y[:metric].nil? ? 0 : y[:metric].to_i) + end.first + + if default_route.nil? or default_route.empty? + Ohai::Log.debug("Unable to determine default #{family[:name]} interface") + else + network["#{default_prefix}_interface"] = default_route[:dev] + Ohai::Log.debug("#{default_prefix}_interface set to #{default_route[:dev]}") + + # setting gateway to 0.0.0.0 or :: if the default route is a link level one + network["#{default_prefix}_gateway"] = default_route[:via] ? default_route[:via] : family[:default_route].chomp("/0") + Ohai::Log.debug("#{default_prefix}_gateway set to #{network["#{default_prefix}_gateway"]}") + + # since we're at it, let's populate {ip,mac,ip6}address with the best values + # using the source field when it's specified : + # 1) in the default route + # 2) in the route entry used to reach the default gateway + route = routes.select do |r| + # selecting routes + r[:src] and # it has a src field + iface[r[:dev]] and # the iface exists + iface[r[:dev]][:addresses].has_key? r[:src] and # the src ip is set on the node + iface[r[:dev]][:addresses][r[:src]][:scope].downcase != "link" and # this isn't a link level addresse + ( r[:destination] == "default" or + ( default_route[:via] and # the default route has a gateway + IPAddress(r[:destination]).include? IPAddress(default_route[:via]) # the route matches the gateway + ) + ) + end.sort_by do |r| + # sorting the selected routes: + # - getting default routes first + # - then sort by metric + # - then by prefixlen + [ + r[:destination] == "default" ? 0 : 1, + r[:metric].nil? ? 0 : r[:metric].to_i, + # for some reason IPAddress doesn't accept "::/0", it doesn't like prefix==0 + # just a quick workaround: use 0 if IPAddress fails + begin + IPAddress( r[:destination] == "default" ? family[:default_route] : r[:destination] ).prefix + rescue + 0 + end + ] + end.first + + unless route.nil? or route.empty? + if family[:name] == "inet" + ipaddress route[:src] + macaddress iface[route[:dev]][:addresses].select{|k,v| v["family"]=="lladdr"}.first.first unless iface[route[:dev]][:flags].include? "NOARP" + else + ip6address route[:src] + end + end + end + end + +else + + begin + route_result = from("route -n \| grep -m 1 ^0.0.0.0").split(/[ \t]+/) + network[:default_gateway], network[:default_interface] = route_result.values_at(1,7) + rescue Ohai::Exceptions::Exec + Ohai::Log.debug("Unable to determine default interface") + end + + popen4("ifconfig -a") do |pid, stdin, stdout, stderr| + stdin.close + cint = nil + stdout.each do |line| + tmp_addr = nil + # dev_valid_name in the kernel only excludes slashes, nulls, spaces + # http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=blob;f=net/core/dev.c#l851 + if line =~ /^([0-9a-zA-Z@\.\:\-_]+)\s+/ + cint = $1 + iface[cint] = Mash.new + if cint =~ /^(\w+)(\d+.*)/ + iface[cint][:type] = $1 + iface[cint][:number] = $2 + end + end + if line =~ /Link encap:(Local Loopback)/ || line =~ /Link encap:(.+?)\s/ + iface[cint][:encapsulation] = encaps_lookup($1) + end + if line =~ /HWaddr (.+?)\s/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "lladdr" } + end + if line =~ /inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "inet" } + tmp_addr = $1 + end + if line =~ /inet6 addr: ([a-f0-9\:]+)\/(\d+) Scope:(\w+)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $2, "scope" => ($3.eql?("Host") ? "Node" : $3) } + end + if line =~ /Bcast:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ + iface[cint][:addresses][tmp_addr]["broadcast"] = $1 + end + if line =~ /Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ + iface[cint][:addresses][tmp_addr]["netmask"] = $1 + end + flags = line.scan(/(UP|BROADCAST|DEBUG|LOOPBACK|POINTTOPOINT|NOTRAILERS|RUNNING|NOARP|PROMISC|ALLMULTI|SLAVE|MASTER|MULTICAST|DYNAMIC)\s/) + if flags.length > 1 + iface[cint][:flags] = flags.flatten + end + if line =~ /MTU:(\d+)/ + iface[cint][:mtu] = $1 + end + if line =~ /P-t-P:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ + iface[cint][:peer] = $1 + end + if line =~ /RX packets:(\d+) errors:(\d+) dropped:(\d+) overruns:(\d+) frame:(\d+)/ + net_counters[cint] = Mash.new unless net_counters[cint] + net_counters[cint][:rx] = { "packets" => $1, "errors" => $2, "drop" => $3, "overrun" => $4, "frame" => $5 } + end + if line =~ /TX packets:(\d+) errors:(\d+) dropped:(\d+) overruns:(\d+) carrier:(\d+)/ + net_counters[cint][:tx] = { "packets" => $1, "errors" => $2, "drop" => $3, "overrun" => $4, "carrier" => $5 } + end + if line =~ /collisions:(\d+)/ + net_counters[cint][:tx]["collisions"] = $1 + end + if line =~ /txqueuelen:(\d+)/ + net_counters[cint][:tx]["queuelen"] = $1 + end + if line =~ /RX bytes:(\d+) \((\d+?\.\d+ .+?)\)/ + net_counters[cint][:rx]["bytes"] = $1 + end + if line =~ /TX bytes:(\d+) \((\d+?\.\d+ .+?)\)/ + net_counters[cint][:tx]["bytes"] = $1 + end + end + end + + + popen4("arp -an") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^\S+ \((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) \[(\w+)\] on ([0-9a-zA-Z\.\:\-]+)/ + next unless iface[$4] # this should never happen + iface[$4][:arp] = Mash.new unless iface[$4][:arp] + iface[$4][:arp][$1] = $2.downcase + end + end + end + +end + + +counters[:network][:interfaces] = net_counters + +network["interfaces"] = iface + diff --git a/spec/data/plugins/v6/linux/platform.rb b/spec/data/plugins/v6/linux/platform.rb new file mode 100644 index 00000000..a7bb6dd0 --- /dev/null +++ b/spec/data/plugins/v6/linux/platform.rb @@ -0,0 +1,116 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +def get_redhatish_platform(contents) + contents[/^Red Hat/i] ? "redhat" : contents[/(\w+)/i, 1].downcase +end + +def get_redhatish_version(contents) + contents[/Rawhide/i] ? contents[/((\d+) \(Rawhide\))/i, 1].downcase : contents[/release ([\d\.]+)/, 1] +end + +provides "platform", "platform_version", "platform_family" + +require_plugin 'linux::lsb' + +# platform [ and platform_version ? ] should be lower case to avoid dealing with RedHat/Redhat/redhat matching +if File.exists?("/etc/oracle-release") + contents = File.read("/etc/oracle-release").chomp + platform "oracle" + platform_version get_redhatish_version(contents) +elsif File.exists?("/etc/enterprise-release") + contents = File.read("/etc/enterprise-release").chomp + platform "oracle" + platform_version get_redhatish_version(contents) +elsif File.exists?("/etc/debian_version") + # Ubuntu, GCEL and Debian both have /etc/debian_version + # Ubuntu, GCEL should always have a working lsb, debian does not by default + if lsb[:id] =~ /Ubuntu/i + platform "ubuntu" + platform_version lsb[:release] + elsif lsb[:id] =~ /gcel/i + platform "gcel" + platform_version lsb[:release] + elsif lsb[:id] =~ /LinuxMint/i + platform "linuxmint" + platform_version lsb[:release] + else + if File.exists?("/usr/bin/raspi-config") + platform "raspbian" + else + platform "debian" + end + platform_version File.read("/etc/debian_version").chomp + end +elsif File.exists?("/etc/redhat-release") + contents = File.read("/etc/redhat-release").chomp + platform get_redhatish_platform(contents) + platform_version get_redhatish_version(contents) +elsif File.exists?("/etc/system-release") + contents = File.read("/etc/system-release").chomp + platform get_redhatish_platform(contents) + platform_version get_redhatish_version(contents) +elsif File.exists?('/etc/gentoo-release') + platform "gentoo" + platform_version File.read('/etc/gentoo-release').scan(/(\d+|\.+)/).join +elsif File.exists?('/etc/SuSE-release') + platform "suse" + suse_release = File.read("/etc/SuSE-release") + platform_version suse_release.scan(/VERSION = (\d+)\nPATCHLEVEL = (\d+)/).flatten.join(".") + platform_version suse_release.scan(/VERSION = ([\d\.]{2,})/).flatten.join(".") if platform_version == "" +elsif File.exists?('/etc/slackware-version') + platform "slackware" + platform_version File.read("/etc/slackware-version").scan(/(\d+|\.+)/).join +elsif File.exists?('/etc/arch-release') + platform "arch" + # no way to determine platform_version in a rolling release distribution + # kernel release will be used - ex. 2.6.32-ARCH +elsif lsb[:id] =~ /RedHat/i + platform "redhat" + platform_version lsb[:release] +elsif lsb[:id] =~ /Amazon/i + platform "amazon" + platform_version lsb[:release] +elsif lsb[:id] =~ /ScientificSL/i + platform "scientific" + platform_version lsb[:release] +elsif lsb[:id] =~ /XenServer/i + platform "xenserver" + platform_version lsb[:release] +elsif lsb[:id] # LSB can provide odd data that changes between releases, so we currently fall back on it rather than dealing with its subtleties + platform lsb[:id].downcase + platform_version lsb[:release] +end + + +case platform + when /debian/, /ubuntu/, /linuxmint/, /raspbian/, /gcel/ + platform_family "debian" + when /fedora/ + platform_family "fedora" + when /oracle/, /centos/, /redhat/, /scientific/, /enterpriseenterprise/, /amazon/, /xenserver/ # Note that 'enterpriseenterprise' is oracle's LSB "distributor ID" + platform_family "rhel" + when /suse/ + platform_family "suse" + when /gentoo/ + platform_family "gentoo" + when /slackware/ + platform_family "slackware" + when /arch/ + platform_family "arch" +end diff --git a/spec/data/plugins/v6/linux/ps.rb b/spec/data/plugins/v6/linux/ps.rb new file mode 100644 index 00000000..ad4760a8 --- /dev/null +++ b/spec/data/plugins/v6/linux/ps.rb @@ -0,0 +1,23 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "command/ps" + +require_plugin 'command' + +command[:ps] = 'ps -ef' diff --git a/spec/data/plugins/v6/linux/uptime.rb b/spec/data/plugins/v6/linux/uptime.rb new file mode 100644 index 00000000..047cfc19 --- /dev/null +++ b/spec/data/plugins/v6/linux/uptime.rb @@ -0,0 +1,28 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "uptime", "idletime", "uptime_seconds", "idletime_seconds" + +uptime, idletime = File.open("/proc/uptime").gets.split(" ") +uptime_seconds uptime.to_i +uptime self._seconds_to_human(uptime.to_i) +idletime_seconds idletime.to_i +idletime self._seconds_to_human(idletime.to_i) + + + diff --git a/spec/data/plugins/v6/linux/virtualization.rb b/spec/data/plugins/v6/linux/virtualization.rb new file mode 100644 index 00000000..9cdaa9b6 --- /dev/null +++ b/spec/data/plugins/v6/linux/virtualization.rb @@ -0,0 +1,125 @@ +# +# Author:: Thom May (<thom@clearairturbulence.org>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "virtualization" + +virtualization Mash.new + +# if it is possible to detect paravirt vs hardware virt, it should be put in +# virtualization[:mechanism] + +## Xen +# /proc/xen is an empty dir for EL6 + Linode Guests +if File.exists?("/proc/xen") + virtualization[:system] = "xen" + # Assume guest + virtualization[:role] = "guest" + + # This file should exist on most Xen systems, normally empty for guests + if File.exists?("/proc/xen/capabilities") + if File.read("/proc/xen/capabilities") =~ /control_d/i + virtualization[:role] = "host" + end + end +end + +# Xen Notes: +# - cpuid of guests, if we could get it, would also be a clue +# - may be able to determine if under paravirt from /dev/xen/evtchn (See OHAI-253) +# - EL6 guests carry a 'hypervisor' cpu flag +# - Additional edge cases likely should not change the above assumptions +# but rather be additive - btm + +# Detect from kernel module +if File.exists?("/proc/modules") + modules = File.read("/proc/modules") + if modules =~ /^kvm/ + virtualization[:system] = "kvm" + virtualization[:role] = "host" + elsif modules =~ /^vboxdrv/ + virtualization[:system] = "vbox" + virtualization[:role] = "host" + elsif modules =~ /^vboxguest/ + virtualization[:system] = "vbox" + virtualization[:role] = "guest" + end +end + +# Detect KVM/QEMU from cpuinfo, report as KVM +# We could pick KVM from 'Booting paravirtualized kernel on KVM' in dmesg +# 2.6.27-9-server (intrepid) has this / 2.6.18-6-amd64 (etch) does not +# It would be great if we could read pv_info in the kernel +# Wait for reply to: http://article.gmane.org/gmane.comp.emulators.kvm.devel/27885 +if File.exists?("/proc/cpuinfo") + if File.read("/proc/cpuinfo") =~ /QEMU Virtual CPU/ + virtualization[:system] = "kvm" + virtualization[:role] = "guest" + end +end + +# Detect OpenVZ / Virtuozzo. +# http://wiki.openvz.org/BC_proc_entries +if File.exists?("/proc/bc/0") + virtualization[:system] = "openvz" + virtualization[:role] = "host" +elsif File.exists?("/proc/vz") + virtualization[:system] = "openvz" + virtualization[:role] = "guest" +end + +# http://www.dmo.ca/blog/detecting-virtualization-on-linux +if File.exists?("/usr/sbin/dmidecode") + popen4("dmidecode") do |pid, stdin, stdout, stderr| + stdin.close + dmi_info = stdout.read + case dmi_info + when /Manufacturer: Microsoft/ + if dmi_info =~ /Product Name: Virtual Machine/ + virtualization[:system] = "virtualpc" + virtualization[:role] = "guest" + end + when /Manufacturer: VMware/ + if dmi_info =~ /Product Name: VMware Virtual Platform/ + virtualization[:system] = "vmware" + virtualization[:role] = "guest" + end + when /Manufacturer: Xen/ + if dmi_info =~ /Product Name: HVM domU/ + virtualization[:system] = "xen" + virtualization[:role] = "guest" + end + else + nil + end + + end +end + +# Detect Linux-VServer +if File.exists?("/proc/self/status") + proc_self_status = File.read("/proc/self/status") + vxid = proc_self_status.match(/^(s_context|VxID): (\d+)$/) + if vxid and vxid[2] + virtualization[:system] = "linux-vserver" + if vxid[2] == "0" + virtualization[:role] = "host" + else + virtualization[:role] = "guest" + end + end +end diff --git a/spec/data/plugins/v6/lua.rb b/spec/data/plugins/v6/lua.rb new file mode 100644 index 00000000..80fb33a5 --- /dev/null +++ b/spec/data/plugins/v6/lua.rb @@ -0,0 +1,34 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2009 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages/lua" + +require_plugin "languages" + +output = nil + +lua = Mash.new + +status, stdout, stderr = run_command(:no_status_check => true, :command => "lua -v") +if status == 0 + output = stderr.split + if output.length >= 1 + lua[:version] = output[1] + end + languages[:lua] = lua if lua[:version] +end diff --git a/spec/data/plugins/v6/mono.rb b/spec/data/plugins/v6/mono.rb new file mode 100644 index 00000000..ca921a9b --- /dev/null +++ b/spec/data/plugins/v6/mono.rb @@ -0,0 +1,37 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2009 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages/mono" + +require_plugin "languages" + +output = nil + +mono = Mash.new + +status, stdout, stderr = run_command(:no_status_check => true, :command => "mono -V") +if status == 0 + output = stdout.split + if output.length >= 4 + mono[:version] = output[4] + end + if output.length >= 11 + mono[:builddate] = "%s %s %s %s" % [output[6],output[7],output[8],output[11].gsub!(/\)/,'')] + end + languages[:mono] = mono if mono[:version] +end diff --git a/spec/data/plugins/v6/netbsd/cpu.rb b/spec/data/plugins/v6/netbsd/cpu.rb new file mode 100644 index 00000000..5063db58 --- /dev/null +++ b/spec/data/plugins/v6/netbsd/cpu.rb @@ -0,0 +1,48 @@ +# +# Author:: Mathieu Sauve-Frankel <msf@kisoku.net> +# Copyright:: Copyright (c) 2009 Mathieu Sauve-Frankel +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides 'cpu' + +cpuinfo = Mash.new + +# NetBSD provides some cpu information via sysctl, and a little via dmesg.boot +# unlike OpenBSD and FreeBSD, NetBSD does not provide information about the +# available instruction set +# cpu0 at mainbus0 apid 0: Intel 686-class, 2134MHz, id 0x6f6 + +File.open("/var/run/dmesg.boot").each do |line| + case line + when /cpu[\d\w\s]+:\s([\w\s\-]+),\s+(\w+),/ + cpuinfo[:model_name] = $1 + cpuinfo[:mhz] = $2.gsub(/mhz/i, "") + end +end + +flags = [] +popen4("dmidecode") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^\s+([A-Z\d-]+)\s+\([\w\s-]+\)$/ + flags << $1.downcase + end + end +end + +cpuinfo[:flags] = flags unless flags.empty? + +cpu cpuinfo diff --git a/spec/data/plugins/v6/netbsd/filesystem.rb b/spec/data/plugins/v6/netbsd/filesystem.rb new file mode 100644 index 00000000..90a76498 --- /dev/null +++ b/spec/data/plugins/v6/netbsd/filesystem.rb @@ -0,0 +1,57 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "filesystem" + +fs = Mash.new + +# Grab filesystem data from df +popen4("df") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^Filesystem/ + next + when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/ + filesystem = $1 + fs[filesystem] = Mash.new + fs[filesystem]['kb_size'] = $2 + fs[filesystem]['kb_used'] = $3 + fs[filesystem]['kb_available'] = $4 + fs[filesystem]['percent_used'] = $5 + fs[filesystem]['mount'] = $6 + end + end +end + +# Grab mount information from mount +popen4("mount -l") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^(.+?) on (.+?) \((.+?), (.+?)\)$/ + filesystem = $1 + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem]['mount'] = $2 + fs[filesystem]['fs_type'] = $3 + fs[filesystem]['mount-options'] = $4.split(/,\s*/) + end + end +end + +# Set the filesystem data +filesystem fs diff --git a/spec/data/plugins/v6/netbsd/hostname.rb b/spec/data/plugins/v6/netbsd/hostname.rb new file mode 100644 index 00000000..337203dd --- /dev/null +++ b/spec/data/plugins/v6/netbsd/hostname.rb @@ -0,0 +1,22 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "hostname", "fqdn" + +hostname from("hostname -s") +fqdn from("hostname") diff --git a/spec/data/plugins/v6/netbsd/kernel.rb b/spec/data/plugins/v6/netbsd/kernel.rb new file mode 100644 index 00000000..d859eef8 --- /dev/null +++ b/spec/data/plugins/v6/netbsd/kernel.rb @@ -0,0 +1,35 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "kernel" + +kernel[:os] = kernel[:name] +kernel[:securelevel] = from_with_regex("sysctl kern.securelevel", /kern.securelevel=(.+)$/) + +mod = Mash.new +popen4("/usr/bin/modstat") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + # 1 7 0xc0400000 97f830 kernel + if line =~ /(\d+)\s+(\d+)\s+([0-9a-fx]+)\s+([0-9a-fx]+)\s+([a-zA-Z0-9\_]+)/ + kld[$5] = { :size => $4, :refcount => $2 } + end + end +end + +kernel[:modules] = mod unless mod.empty? diff --git a/spec/data/plugins/v6/netbsd/memory.rb b/spec/data/plugins/v6/netbsd/memory.rb new file mode 100644 index 00000000..62772d5e --- /dev/null +++ b/spec/data/plugins/v6/netbsd/memory.rb @@ -0,0 +1,98 @@ +# +# Author:: Mathieu Sauve-Frankel <msf@kisoku.net> +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "memory" + +memory Mash.new +memory[:swap] = Mash.new + +# $ vmstat -s +# 4096 bytes per page +# 514011 pages managed +# 224519 pages free +# 209339 pages active +# 4647 pages inactive +# 0 pages being paged out +# 5 pages wired +# 0 pages zeroed +# 4 pages reserved for pagedaemon +# 6 pages reserved for kernel +# 262205 swap pages +# 0 swap pages in use +# 0 total anon's in system +# 0 free anon's +# 1192991609 page faults +# 1369579301 traps +# 814549706 interrupts +# 771702498 cpu context switches +# 208810590 fpu context switches +# 492361360 software interrupts +# 1161998825 syscalls +# 0 pagein operations +# 0 swap ins +# 0 swap outs +# 768352 forks +# 16 forks where vmspace is shared +# 1763 kernel map entries +# 0 number of times the pagedaemon woke up +# 0 revolutions of the clock hand +# 0 pages freed by pagedaemon +# 0 pages scanned by pagedaemon +# 0 pages reactivated by pagedaemon +# 0 busy pages found by pagedaemon +# 1096393776 total name lookups +# cache hits (37% pos + 2% neg) system 1% per-directory +# deletions 0%, falsehits 6%, toolong 26% +# 0 select collisions + +popen4("vmstat -s") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /(\d+) bytes per page/ + memory[:page_size] = $1 + when /(\d+) pages managed/ + memory[:page_count] = $1 + memory[:total] = memory[:page_size].to_i * memory[:page_count].to_i + when /(\d+) pages free/ + memory[:free] = memory[:page_size].to_i * $1.to_i + when /(\d+) pages active/ + memory[:active] = memory[:page_size].to_i * $1.to_i + when /(\d+) pages inactive/ + memory[:inactive] = memory[:page_size].to_i * $1.to_i + when /(\d+) pages wired/ + memory[:wired] = memory[:page_size].to_i * $1.to_i + end + end +end + +popen4("swapctl -l") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + # Device 1024-blocks Used Avail Capacity Priority + # swap_device 1048824 0 1048824 0% 0 + if line =~ /^([\d\w\/]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d\%]+)/ + mdev = $1 + memory[:swap][mdev] = Mash.new + memory[:swap][mdev][:total] = $2 + memory[:swap][mdev][:used] = $3 + memory[:swap][mdev][:free] = $4 + memory[:swap][mdev][:percent_free] = $5 + end + end +end diff --git a/spec/data/plugins/v6/netbsd/network.rb b/spec/data/plugins/v6/netbsd/network.rb new file mode 100644 index 00000000..55c0c229 --- /dev/null +++ b/spec/data/plugins/v6/netbsd/network.rb @@ -0,0 +1,120 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "network", "counters/network" + +from("route -n get default").split("\n").each do |line| + if line =~ /(\w+): ([\w\.]+)/ + case $1 + when "gateway" + network[:default_gateway] = $2 + when "interface" + network[:default_interface] = $2 + end + end +end + +iface = Mash.new +popen4("/sbin/ifconfig -a") do |pid, stdin, stdout, stderr| + stdin.close + cint = nil + stdout.each do |line| + if line =~ /^([0-9a-zA-Z\.]+):\s+/ + cint = $1 + iface[cint] = Mash.new + if cint =~ /^(\w+)(\d+.*)/ + iface[cint][:type] = $1 + iface[cint][:number] = $2 + end + end + # call the family lladdr to match linux for consistency + if line =~ /\s+address: (.+?)\s/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "lladdr" } + end + if line =~ /\s+inet ([\d.]+) netmask ([\da-fx]+)\s*\w*\s*([\d.]*)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + # convert the netmask to decimal for consistency + netmask = "#{$2[2,2].hex}.#{$2[4,2].hex}.#{$2[6,2].hex}.#{$2[8,2].hex}" + if $3.empty? + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask } + else + # found a broadcast address + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask, "broadcast" => $3 } + end + end + if line =~ /\s+inet6 ([a-f0-9\:]+)%?(\w*)\s+prefixlen\s+(\d+)\s*\w*\s*([\da-fx]*)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + if $4.empty? + iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $3 } + else + #found a zone_id / scope + iface[cint][:addresses][$1] = { "family" => "inet6", "zoneid" => $2, "prefixlen" => $3, "scopeid" => $4 } + end + end + if line =~ /flags=\d+<(.+)>/ + flags = $1.split(',') + iface[cint][:flags] = flags if flags.length > 0 + end + if line =~ /metric: (\d+) mtu: (\d+)/ + iface[cint][:metric] = $1 + iface[cint][:mtu] = $2 + end + end +end + +popen4("arp -an") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) on ([0-9a-zA-Z\.\:\-]+)/ + next unless iface[$3] # this should never happen + iface[$3][:arp] = Mash.new unless iface[$3][:arp] + iface[$3][:arp][$1] = $2.downcase + end + end +end + +network["interfaces"] = iface + +net_counters = Mash.new +# From netstat(1), not sure of the implications: +# Show the state of all network interfaces or a single interface +# which have been auto-configured (interfaces statically configured +# into a system, but not located at boot time are not shown). +popen4("netstat -idn") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + # Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll Drop + # em0 1500 <Link> 00:11:25:2d:90:be 3719557 0 3369969 0 0 0 + # $1 $2 $3 $4 $5 $6 $7 $8 + if line =~ /^([\w\.\*]+)\s+\d+\s+<Link>\s+([\w:]*)\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ + cint = $1 + net_counters[cint] = Mash.new unless net_counters[cint] + net_counters[cint] = Mash.new unless net_counters[cint]["rx"] + net_counters[cint] = Mash.new unless net_counters[cint]["tx"] + net_counters[cint] = $3 + net_counters[cint] = $4 + net_counters[cint] = $5 + net_counters[cint] = $6 + net_counters[cint] = $7 + net_counters[cint] = $8 + end + end +end + +counters[:network][:interfaces] = net_counters diff --git a/spec/data/plugins/v6/netbsd/platform.rb b/spec/data/plugins/v6/netbsd/platform.rb new file mode 100644 index 00000000..f1c96516 --- /dev/null +++ b/spec/data/plugins/v6/netbsd/platform.rb @@ -0,0 +1,22 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "platform", "platform_version" + +platform from("uname -s").downcase +platform_version from("uname -r") diff --git a/spec/data/plugins/v6/netbsd/ps.rb b/spec/data/plugins/v6/netbsd/ps.rb new file mode 100644 index 00000000..dce923cf --- /dev/null +++ b/spec/data/plugins/v6/netbsd/ps.rb @@ -0,0 +1,24 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "command/ps" + +require_plugin 'command' + +# ps -e requires procfs +command[:ps] = 'ps -ax' diff --git a/spec/data/plugins/v6/netbsd/uptime.rb b/spec/data/plugins/v6/netbsd/uptime.rb new file mode 100644 index 00000000..85f3588a --- /dev/null +++ b/spec/data/plugins/v6/netbsd/uptime.rb @@ -0,0 +1,31 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "uptime", "uptime_seconds" + +# kern.boottime: { sec = 1232765114, usec = 823118 } Fri Jan 23 18:45:14 2009 + +popen4("/sbin/sysctl kern.boottime") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /kern.boottime:\D+(\d+)/ + uptime_seconds Time.new.to_i - $1.to_i + uptime self._seconds_to_human(uptime_seconds) + end + end +end diff --git a/spec/data/plugins/v6/netbsd/virtualization.rb b/spec/data/plugins/v6/netbsd/virtualization.rb new file mode 100644 index 00000000..4e085dea --- /dev/null +++ b/spec/data/plugins/v6/netbsd/virtualization.rb @@ -0,0 +1,65 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "virtualization" + +virtualization Mash.new + +# KVM Host support for FreeBSD is in development +# http://feanor.sssup.it/~fabio/freebsd/lkvm/ + +# Detect KVM/QEMU from cpu, report as KVM +# hw.model: QEMU Virtual CPU version 0.9.1 +if from("sysctl -n hw.model") =~ /QEMU Virtual CPU/ + virtualization[:system] = "kvm" + virtualization[:role] = "guest" +end + +# http://www.dmo.ca/blog/detecting-virtualization-on-linux +if File.exists?("/usr/pkg/sbin/dmidecode") + popen4("dmidecode") do |pid, stdin, stdout, stderr| + stdin.close + found_virt_manufacturer = nil + found_virt_product = nil + stdout.each do |line| + case line + when /Manufacturer: Microsoft/ + found_virt_manufacturer = "microsoft" + when /Product Name: Virtual Machine/ + found_virt_product = "microsoft" + when /Version: 5.0/ + if found_virt_manufacturer == "microsoft" && found_virt_product == "microsoft" + virtualization[:system] = "virtualpc" + virtualization[:role] = "guest" + end + when /Version: VS2005R2/ + if found_virt_manufacturer == "microsoft" && found_virt_product == "microsoft" + virtualization[:system] = "virtualserver" + virtualization[:role] = "guest" + end + when /Manufacturer: VMware/ + found_virt_manufacturer = "vmware" + when /Product Name: VMware Virtual Platform/ + if found_virt_manufacturer == "vmware" + virtualization[:system] = "vmware" + virtualization[:role] = "guest" + end + end + end + end +end diff --git a/spec/data/plugins/v6/network.rb b/spec/data/plugins/v6/network.rb new file mode 100644 index 00000000..cf572567 --- /dev/null +++ b/spec/data/plugins/v6/network.rb @@ -0,0 +1,175 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'ipaddress' + +provides "network", "counters/network" + +network Mash.new unless network +network[:interfaces] = Mash.new unless network[:interfaces] +counters Mash.new unless counters +counters[:network] = Mash.new unless counters[:network] + +require_plugin "hostname" +require_plugin "#{os}::network" + +FAMILIES = { + "inet" => "default", + "inet6" => "default_inet6" +} + +def sorted_ips(family = "inet") + raise "bad family #{family}" unless [ "inet", "inet6" ].include? family + + # going to use that later to sort by scope + scope_prio = [ "global", "site", "link", "host", "node", nil ] + + ipaddresses = [] + # ipaddresses going to hold #{family} ipaddresses and their scope + Mash[network['interfaces']].each do |iface, iface_v| + iface_v['addresses'].each do |addr, addr_v| + next if addr_v.nil? or not addr_v.has_key? "family" or addr_v['family'] != family + ipaddresses << { + :ipaddress => addr_v["prefixlen"] ? IPAddress("#{addr}/#{addr_v["prefixlen"]}") : IPAddress("#{addr}/#{addr_v["netmask"]}"), + :scope => addr_v["scope"].nil? ? nil : addr_v["scope"].downcase, + :iface => iface + } + end + end + + # sort ip addresses by scope, by prefixlen and then by ip address + # 128 - prefixlen: longest prefixes first + ipaddresses.sort_by do |v| + [ ( scope_prio.index(v[:scope]) or 999999 ), + 128 - v[:ipaddress].prefix.to_i, + ( family == "inet" ? v[:ipaddress].to_u32 : v[:ipaddress].to_u128 ) + ] + end +end + +def find_ip(family = "inet") + ips=sorted_ips(family) + + # return if there isn't any #{family} address ! + return [ nil, nil ] if ips.empty? + + # shortcuts to access default #{family} interface and gateway + int_attr = FAMILIES[family] +"_interface" + gw_attr = FAMILIES[family] + "_gateway" + + # If we have a default interface that has addresses, + # populate the short-cut attributes ipaddress, ip6address and macaddress + if network[int_attr] + + # working with the address(es) of the default network interface + gw_if_ips = ips.select do |v| + v[:iface] == network[int_attr] + end + if gw_if_ips.empty? + Ohai::Log.warn("[#{family}] no ip address on #{network[int_attr]}") + elsif network[gw_attr] and + network["interfaces"][network[int_attr]] and + network["interfaces"][network[int_attr]]["addresses"] + if [ "0.0.0.0", "::" ].include? network[gw_attr] + # link level default route + Ohai::Log.debug("link level default #{family} route, picking ip from #{network[gw_attr]}") + r = gw_if_ips.first + else + # checking network masks + r = gw_if_ips.select do |v| + network_contains_address(network[gw_attr], v[:ipaddress], v[:iface]) + end.first + if r.nil? + r = gw_if_ips.first + Ohai::Log.warn("[#{family}] no ipaddress/mask on #{network[int_attr]} matching the gateway #{network[gw_attr]}, picking one anyway") + else + Ohai::Log.debug("[#{family}] Using default interface #{network[int_attr]} and default gateway #{network[gw_attr]} to set the default ip to #{r[:ipaddress]}") + end + end + else + # return the first ip address on network[int_attr] + r = gw_if_ips.first + end + else + r = ips.first + Ohai::Log.debug("[#{family}] no default interface, picking the first ipaddress") + end + + return [ nil, nil ] if r.nil? or r.empty? + + [ r[:ipaddress].to_s, r[:iface] ] +end + +def find_mac_from_iface(iface) + r = network["interfaces"][iface]["addresses"].select{|k,v| v["family"]=="lladdr"} + r.nil? or r.first.nil? ? nil : r.first.first +end + +def network_contains_address(address_to_match, ipaddress, iface) + # address_to_match: String + # ipaddress: IPAddress + # iface: String + if peer = network["interfaces"][iface]["addresses"][ipaddress.to_s][:peer] + IPAddress(peer) == IPAddress(address_to_match) + else + ipaddress.include? IPAddress(address_to_match) + end +end + +# ipaddress, ip6address and macaddress can be set by the #{os}::network plugin +# atm it is expected macaddress is set at the same time than ipaddress +# if ipaddress is set and macaddress is nil, that means the interface +# ipaddress is bound to has the NOARP flag + + +results = {} + +# inet family is treated before inet6 +FAMILIES.keys.sort.each do |family| + r = {} + ( r["ip"], r["iface"] ) = find_ip(family) + r["mac"] = find_mac_from_iface(r["iface"]) unless r["iface"].nil? + # don't overwrite attributes if they've already been set by the "#{os}::network" plugin + if family == "inet" and ipaddress.nil? + if r["ip"].nil? + Ohai::Log.warn("unable to detect ipaddress") + # i don't issue this warning if r["ip"] exists and r["mac"].nil? + # as it could be a valid setup with a NOARP default_interface + Ohai::Log.warn("unable to detect macaddress") + else + ipaddress r["ip"] + macaddress r["mac"] + end + elsif family == "inet6" and ip6address.nil? + if r["ip"].nil? + Ohai::Log.warn("unable to detect ip6address") + else + ip6address r["ip"] + if r["mac"] and macaddress.nil? and ipaddress.nil? + Ohai::Log.debug("macaddress set to #{r["mac"]} from the ipv6 setup") + macaddress r["mac"] + end + end + end + results[family] = r +end + +if results["inet"]["iface"] and results["inet6"]["iface"] and + results["inet"]["iface"] != results["inet6"]["iface"] + Ohai::Log.debug("ipaddress and ip6address are set from different interfaces (#{results["inet"]["iface"]} & #{results["inet6"]["iface"]}), macaddress has been set using the ipaddress interface") +end diff --git a/spec/data/plugins/v6/network_listeners.rb b/spec/data/plugins/v6/network_listeners.rb new file mode 100644 index 00000000..4d4c332f --- /dev/null +++ b/spec/data/plugins/v6/network_listeners.rb @@ -0,0 +1,47 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2009 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'sigar' + +provides "network/listeners" + +require_plugin "network" + +flags = Sigar::NETCONN_TCP|Sigar::NETCONN_SERVER + +listeners = Mash.new + +sigar = Sigar.new +sigar.net_connection_list(flags).each do |conn| + port = conn.local_port + addr = conn.local_address.to_s + if addr == "0.0.0.0" || addr == "::" + addr = "*" + end + listeners[port] = Mash.new + listeners[port][:address] = addr + begin + pid = sigar.proc_port(conn.type, port) + listeners[port][:pid] = pid + listeners[port][:name] = sigar.proc_state(pid).name + rescue + end +end + +network[:listeners] = Mash.new +network[:listeners][:tcp] = listeners diff --git a/spec/data/plugins/v6/nodejs.rb b/spec/data/plugins/v6/nodejs.rb new file mode 100644 index 00000000..05acac09 --- /dev/null +++ b/spec/data/plugins/v6/nodejs.rb @@ -0,0 +1,34 @@ +# +# Author:: Jacques Marneweck (<jacques@powertrip.co.za>) +# Copyright:: Copyright (c) 2012 Jacques Marneweck. All rights reserved. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages/nodejs" + +require_plugin "languages" + +output = nil + +nodejs = Mash.new + +status, stdout, stderr = run_command(:no_status_check => true, :command => "node -v") +if status == 0 + output = stdout.split + if output.length >= 1 + nodejs[:version] = output[0][1..output[0].length] + end + languages[:nodejs] = nodejs if nodejs[:version] +end diff --git a/spec/data/plugins/v6/ohai.rb b/spec/data/plugins/v6/ohai.rb new file mode 100644 index 00000000..666bdefe --- /dev/null +++ b/spec/data/plugins/v6/ohai.rb @@ -0,0 +1,25 @@ +# +# Author:: Tollef Fog Heen <tfheen@err.no> +# Copyright:: Copyright (c) 2010 Tollef Fog Heen +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "ohai" +provides "ohai" + +self[:chef_packages] = Mash.new unless self[:chef_packages] +self[:chef_packages][:ohai] = Mash.new +self[:chef_packages][:ohai][:version] = Ohai::VERSION +self[:chef_packages][:ohai][:ohai_root] = Ohai::OHAI_ROOT diff --git a/spec/data/plugins/v6/ohai_time.rb b/spec/data/plugins/v6/ohai_time.rb new file mode 100644 index 00000000..643772b9 --- /dev/null +++ b/spec/data/plugins/v6/ohai_time.rb @@ -0,0 +1,21 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "ohai_time" + +ohai_time Time.now.to_f
\ No newline at end of file diff --git a/spec/data/plugins/v6/openbsd/cpu.rb b/spec/data/plugins/v6/openbsd/cpu.rb new file mode 100644 index 00000000..d350ada0 --- /dev/null +++ b/spec/data/plugins/v6/openbsd/cpu.rb @@ -0,0 +1,38 @@ +# +# Author:: Mathieu Sauve-Frankel <msf@kisoku.net> +# Copyright:: Copyright (c) 2009 Mathieu Sauve-Frankel +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides 'cpu' + +cpuinfo = Mash.new + +# OpenBSD provides most cpu information via sysctl, the only thing we need to +# to scrape from dmesg.boot is the cpu feature list. +# cpu0: FPU,V86,DE,PSE,TSC,MSR,MCE,CX8,SEP,MTRR,PGE,MCA,CMOV,PAT,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,TM,SBF,EST,TM2 + +File.open("/var/run/dmesg.boot").each do |line| + case line + when /cpu\d+:\s+([A-Z]+$|[A-Z]+,.*$)/ + cpuinfo["flags"] = $1.downcase.split(',') + end +end + +cpuinfo[:model_name] = from("sysctl -n hw.model") +cpuinfo[:total] = from("sysctl -n hw.ncpu") +cpuinfo[:mhz] = from("sysctl -n hw.cpuspeed") + +cpu cpuinfo diff --git a/spec/data/plugins/v6/openbsd/filesystem.rb b/spec/data/plugins/v6/openbsd/filesystem.rb new file mode 100644 index 00000000..90a76498 --- /dev/null +++ b/spec/data/plugins/v6/openbsd/filesystem.rb @@ -0,0 +1,57 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "filesystem" + +fs = Mash.new + +# Grab filesystem data from df +popen4("df") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^Filesystem/ + next + when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/ + filesystem = $1 + fs[filesystem] = Mash.new + fs[filesystem]['kb_size'] = $2 + fs[filesystem]['kb_used'] = $3 + fs[filesystem]['kb_available'] = $4 + fs[filesystem]['percent_used'] = $5 + fs[filesystem]['mount'] = $6 + end + end +end + +# Grab mount information from mount +popen4("mount -l") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /^(.+?) on (.+?) \((.+?), (.+?)\)$/ + filesystem = $1 + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem]['mount'] = $2 + fs[filesystem]['fs_type'] = $3 + fs[filesystem]['mount-options'] = $4.split(/,\s*/) + end + end +end + +# Set the filesystem data +filesystem fs diff --git a/spec/data/plugins/v6/openbsd/hostname.rb b/spec/data/plugins/v6/openbsd/hostname.rb new file mode 100644 index 00000000..337203dd --- /dev/null +++ b/spec/data/plugins/v6/openbsd/hostname.rb @@ -0,0 +1,22 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "hostname", "fqdn" + +hostname from("hostname -s") +fqdn from("hostname") diff --git a/spec/data/plugins/v6/openbsd/kernel.rb b/spec/data/plugins/v6/openbsd/kernel.rb new file mode 100644 index 00000000..38d14e81 --- /dev/null +++ b/spec/data/plugins/v6/openbsd/kernel.rb @@ -0,0 +1,35 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "kernel" + +kernel[:os] = kernel[:name] +kernel[:securelevel] = from_with_regex("sysctl kern.securelevel", /kern.securelevel=(.+)$/) + +mod = Mash.new +popen4("/usr/bin/modstat") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + # 1 7 0xc0400000 97f830 kernel + if line =~ /(\d+)\s+(\d+)\s+([0-9a-fx]+)\s+([0-9a-fx]+)\s+([a-zA-Z0-9\_]+)/ + kld[$5] = { :size => $4, :refcount => $2 } + end + end +end + +kernel[:modules] = mod unless mod.empty? diff --git a/spec/data/plugins/v6/openbsd/memory.rb b/spec/data/plugins/v6/openbsd/memory.rb new file mode 100644 index 00000000..54f554bf --- /dev/null +++ b/spec/data/plugins/v6/openbsd/memory.rb @@ -0,0 +1,98 @@ +# +# Author:: Mathieu Sauve-Frankel <msf@kisoku.net> +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "memory" + +memory Mash.new +memory[:swap] = Mash.new + +# $ vmstat -s +# 4096 bytes per page +# 514011 pages managed +# 224519 pages free +# 209339 pages active +# 4647 pages inactive +# 0 pages being paged out +# 5 pages wired +# 0 pages zeroed +# 4 pages reserved for pagedaemon +# 6 pages reserved for kernel +# 262205 swap pages +# 0 swap pages in use +# 0 total anon's in system +# 0 free anon's +# 1192991609 page faults +# 1369579301 traps +# 814549706 interrupts +# 771702498 cpu context switches +# 208810590 fpu context switches +# 492361360 software interrupts +# 1161998825 syscalls +# 0 pagein operations +# 0 swap ins +# 0 swap outs +# 768352 forks +# 16 forks where vmspace is shared +# 1763 kernel map entries +# 0 number of times the pagedaemon woke up +# 0 revolutions of the clock hand +# 0 pages freed by pagedaemon +# 0 pages scanned by pagedaemon +# 0 pages reactivated by pagedaemon +# 0 busy pages found by pagedaemon +# 1096393776 total name lookups +# cache hits (37% pos + 2% neg) system 1% per-directory +# deletions 0%, falsehits 6%, toolong 26% +# 0 select collisions + +popen4("vmstat -s") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /(\d+) bytes per page/ + memory[:page_size] = $1 + when /(\d+) pages managed/ + memory[:page_count] = $1 + memory[:total] = memory[:page_size].to_i * memory[:page_count].to_i + when /(\d+) pages free/ + memory[:free] = memory[:page_size].to_i * $1.to_i + when /(\d+) pages active/ + memory[:active] = memory[:page_size].to_i * $1.to_i + when /(\d+) pages inactive/ + memory[:inactive] = memory[:page_size].to_i * $1.to_i + when /(\d+) pages wired/ + memory[:wired] = memory[:page_size].to_i * $1.to_i + end + end +end + +popen4("swapctl -l") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + # Device 1024-blocks Used Avail Capacity Priority + # swap_device 1048824 0 1048824 0% 0 + if line =~ /^([\d\w\/]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d\%]+)/ + mdev = $1 + memory[:swap][mdev] = Mash.new + memory[:swap][mdev][:total] = $2 + memory[:swap][mdev][:used] = $3 + memory[:swap][mdev][:free] = $4 + memory[:swap][mdev][:percent_free] = $5 + end + end +end diff --git a/spec/data/plugins/v6/openbsd/network.rb b/spec/data/plugins/v6/openbsd/network.rb new file mode 100644 index 00000000..4a3c18ef --- /dev/null +++ b/spec/data/plugins/v6/openbsd/network.rb @@ -0,0 +1,120 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "network", "counters/network" + +from("route -n get default").split("\n").each do |line| + if line =~ /(\w+): ([\w\.]+)/ + case $1 + when "gateway" + network[:default_gateway] = $2 + when "interface" + network[:default_interface] = $2 + end + end +end + +iface = Mash.new +popen4("/sbin/ifconfig -a") do |pid, stdin, stdout, stderr| + stdin.close + cint = nil + stdout.each do |line| + if line =~ /^([0-9a-zA-Z\.]+):\s+/ + cint = $1 + iface[cint] = Mash.new + if cint =~ /^(\w+)(\d+.*)/ + iface[cint][:type] = $1 + iface[cint][:number] = $2 + end + end + # call the family lladdr to match linux for consistency + if line =~ /\s+lladdr (.+?)\s/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "lladdr" } + end + if line =~ /\s+inet ([\d.]+) netmask ([\da-fx]+)\s*\w*\s*([\d.]*)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + # convert the netmask to decimal for consistency + netmask = "#{$2[2,2].hex}.#{$2[4,2].hex}.#{$2[6,2].hex}.#{$2[8,2].hex}" + if $3.empty? + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask } + else + # found a broadcast address + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => netmask, "broadcast" => $3 } + end + end + if line =~ /\s+inet6 ([a-f0-9\:]+)%?(\w*)\s+prefixlen\s+(\d+)\s*\w*\s*([\da-fx]*)/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + if $4.empty? + iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $3 } + else + #found a zone_id / scope + iface[cint][:addresses][$1] = { "family" => "inet6", "zoneid" => $2, "prefixlen" => $3, "scopeid" => $4 } + end + end + if line =~ /flags=\d+<(.+)>/ + flags = $1.split(',') + iface[cint][:flags] = flags if flags.length > 0 + end + if line =~ /metric: (\d+) mtu: (\d+)/ + iface[cint][:metric] = $1 + iface[cint][:mtu] = $2 + end + end +end + +popen4("arp -an") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /\((\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\) at ([a-fA-F0-9\:]+) on ([0-9a-zA-Z\.\:\-]+)/ + next unless iface[$3] # this should never happen + iface[$3][:arp] = Mash.new unless iface[$3][:arp] + iface[$3][:arp][$1] = $2.downcase + end + end +end + +network["interfaces"] = iface + +net_counters = Mash.new +# From netstat(1), not sure of the implications: +# Show the state of all network interfaces or a single interface +# which have been auto-configured (interfaces statically configured +# into a system, but not located at boot time are not shown). +popen4("netstat -idn") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + # Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll Drop + # em0 1500 <Link> 00:11:25:2d:90:be 3719557 0 3369969 0 0 0 + # $1 $2 $3 $4 $5 $6 $7 $8 + if line =~ /^([\w\.\*]+)\s+\d+\s+<Link>\s+([\w:]*)\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ + cint = $1 + net_counters[cint] = Mash.new unless net_counters[cint] + net_counters[cint] = Mash.new unless net_counters[cint]["rx"] + net_counters[cint] = Mash.new unless net_counters[cint]["tx"] + net_counters[cint] = $3 + net_counters[cint] = $4 + net_counters[cint] = $5 + net_counters[cint] = $6 + net_counters[cint] = $7 + net_counters[cint] = $8 + end + end +end + +counters[:network][:interfaces] = net_counters diff --git a/spec/data/plugins/v6/openbsd/platform.rb b/spec/data/plugins/v6/openbsd/platform.rb new file mode 100644 index 00000000..78697e72 --- /dev/null +++ b/spec/data/plugins/v6/openbsd/platform.rb @@ -0,0 +1,23 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "platform", "platform_version" + +platform from("uname -s").downcase +platform_version from("uname -r") + diff --git a/spec/data/plugins/v6/openbsd/ps.rb b/spec/data/plugins/v6/openbsd/ps.rb new file mode 100644 index 00000000..f4823327 --- /dev/null +++ b/spec/data/plugins/v6/openbsd/ps.rb @@ -0,0 +1,24 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "command/ps" + +require_plugin 'command' + +# ps -e requires procfs +command[:ps] = 'ps -ax' diff --git a/spec/data/plugins/v6/openbsd/uptime.rb b/spec/data/plugins/v6/openbsd/uptime.rb new file mode 100644 index 00000000..3d903321 --- /dev/null +++ b/spec/data/plugins/v6/openbsd/uptime.rb @@ -0,0 +1,32 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "uptime", "uptime_seconds" + +# kern.boottime=Tue Nov 1 14:45:52 2011 + +popen4("/sbin/sysctl kern.boottime") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /kern.boottime=(.+)/ + uptime_seconds Time.new.to_i - Time.parse($1).to_i + uptime self._seconds_to_human(uptime_seconds) + end + end +end + diff --git a/spec/data/plugins/v6/openbsd/virtualization.rb b/spec/data/plugins/v6/openbsd/virtualization.rb new file mode 100644 index 00000000..f351e4af --- /dev/null +++ b/spec/data/plugins/v6/openbsd/virtualization.rb @@ -0,0 +1,66 @@ +# +# Author:: Bryan McLellan (btm@loftninjas.org) +# Copyright:: Copyright (c) 2009 Bryan McLellan +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "virtualization" + +virtualization Mash.new + +# KVM Host support for FreeBSD is in development +# http://feanor.sssup.it/~fabio/freebsd/lkvm/ + +# Detect KVM/QEMU from cpu, report as KVM +# hw.model: QEMU Virtual CPU version 0.9.1 +if from("sysctl -n hw.model") =~ /QEMU Virtual CPU/ + virtualization[:system] = "kvm" + virtualization[:role] = "guest" +end + +# http://www.dmo.ca/blog/detecting-virtualization-on-linux +if File.exists?("/usr/local/sbin/dmidecode") + popen4("dmidecode") do |pid, stdin, stdout, stderr| + stdin.close + found_virt_manufacturer = nil + found_virt_product = nil + stdout.each do |line| + case line + when /Manufacturer: Microsoft/ + found_virt_manufacturer = "microsoft" + when /Product Name: Virtual Machine/ + found_virt_product = "microsoft" + when /Version: 5.0/ + if found_virt_manufacturer == "microsoft" && found_virt_product == "microsoft" + virtualization[:system] = "virtualpc" + virtualization[:role] = "guest" + end + when /Version: VS2005R2/ + if found_virt_manufacturer == "microsoft" && found_virt_product == "microsoft" + virtualization[:system] = "virtualserver" + virtualization[:role] = "guest" + end + when /Manufacturer: VMware/ + found_virt_manufacturer = "vmware" + when /Product Name: VMware Virtual Platform/ + if found_virt_manufacturer == "vmware" + virtualization[:system] = "vmware" + virtualization[:role] = "guest" + end + end + end + end +end + diff --git a/spec/data/plugins/v6/openstack.rb b/spec/data/plugins/v6/openstack.rb new file mode 100644 index 00000000..4c9711a7 --- /dev/null +++ b/spec/data/plugins/v6/openstack.rb @@ -0,0 +1,46 @@ +# +# Author:: Matt Ray (<matt@opscode.com>) +# Copyright:: Copyright (c) 2012 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provides "openstack" + +require 'ohai/mixin/ec2_metadata' + +extend Ohai::Mixin::Ec2Metadata + +# does it matter that it's not hitting latest? +#Ec2Metadata::EC2_METADATA_URL = "/latest/meta-data" + +# Adds openstack Mash +if hint?('openstack') || hint?('hp') + Ohai::Log.debug("ohai openstack") + openstack Mash.new + #for now, use the metadata service + if can_metadata_connect?(EC2_METADATA_ADDR,80) + Ohai::Log.debug("connecting to the OpenStack metadata service") + self.fetch_metadata.each {|k, v| openstack[k] = v } + case + when hint?('hp') + openstack['provider'] = 'hp' + else + openstack['provider'] = 'openstack' + end + else + Ohai::Log.debug("unable to connect to the OpenStack metadata service") + end +else + Ohai::Log.debug("NOT ohai openstack") +end diff --git a/spec/data/plugins/v6/os.rb b/spec/data/plugins/v6/os.rb new file mode 100644 index 00000000..7e0d2a92 --- /dev/null +++ b/spec/data/plugins/v6/os.rb @@ -0,0 +1,53 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "os", "os_version" + +require 'rbconfig' + +require_plugin 'kernel' + +case ::RbConfig::CONFIG['host_os'] +when /aix(.+)$/ + os "aix" +when /darwin(.+)$/ + os "darwin" +when /hpux(.+)$/ + os "hpux" +when /linux/ + os "linux" +when /freebsd(.+)$/ + os "freebsd" +when /openbsd(.+)$/ + os "openbsd" +when /netbsd(.*)$/ + os "netbsd" +when /solaris2/ + os "solaris2" +when /mswin|mingw32|windows/ + # After long discussion in IRC the "powers that be" have come to a concensus + # that there is no other Windows platforms exist that were not based on the + # Windows_NT kernel, so we herby decree that "windows" will refer to all + # platforms built upon the Windows_NT kernel and have access to win32 or win64 + # subsystems. + os "windows" +else + os ::RbConfig::CONFIG['host_os'] +end + +os_version kernel[:release] diff --git a/spec/data/plugins/v6/passwd.rb b/spec/data/plugins/v6/passwd.rb new file mode 100644 index 00000000..ed63d268 --- /dev/null +++ b/spec/data/plugins/v6/passwd.rb @@ -0,0 +1,32 @@ +provides 'etc', 'current_user' + +require 'etc' + +def fix_encoding(str) + str.force_encoding(Encoding.default_external) if str.respond_to?(:force_encoding) + str +end + +unless etc + etc Mash.new + + etc[:passwd] = Mash.new + etc[:group] = Mash.new + + Etc.passwd do |entry| + user_passwd_entry = Mash.new(:dir => entry.dir, :gid => entry.gid, :uid => entry.uid, :shell => entry.shell, :gecos => entry.gecos) + user_passwd_entry.each_value {|v| fix_encoding(v)} + etc[:passwd][fix_encoding(entry.name)] = user_passwd_entry + end + + Etc.group do |entry| + group_entry = Mash.new(:gid => entry.gid, + :members => entry.mem.map {|u| fix_encoding(u)}) + + etc[:group][fix_encoding(entry.name)] = group_entry + end +end + +unless current_user + current_user fix_encoding(Etc.getlogin) +end diff --git a/spec/data/plugins/v6/perl.rb b/spec/data/plugins/v6/perl.rb new file mode 100644 index 00000000..00d1e0f0 --- /dev/null +++ b/spec/data/plugins/v6/perl.rb @@ -0,0 +1,39 @@ +# +# Author:: Joshua Timberman (<joshua@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages/perl" + +require_plugin "languages" +output = nil + +perl = Mash.new +status, stdout, stderr = run_command(:no_status_check => true, :command => "perl -V:version -V:archname") +if status == 0 + stdout.each_line do |line| + case line + when /^version=\'(.+)\';$/ + perl[:version] = $1 + when /^archname=\'(.+)\';$/ + perl[:archname] = $1 + end + end +end + +if status == 0 + languages[:perl] = perl +end diff --git a/spec/data/plugins/v6/php.rb b/spec/data/plugins/v6/php.rb new file mode 100644 index 00000000..23dbba14 --- /dev/null +++ b/spec/data/plugins/v6/php.rb @@ -0,0 +1,36 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2009 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages/php" + +require_plugin "languages" + +output = nil + +php = Mash.new + +status, stdout, stderr = run_command(:no_status_check => true, :command => "php -v") +if status == 0 + output = stdout.split + if output.length >= 6 + php[:version] = output[1] + php[:builddate] = "%s %s %s" % [output[4],output[5],output[6]] + end + languages[:php] = php if php[:version] +end + diff --git a/spec/data/plugins/v6/platform.rb b/spec/data/plugins/v6/platform.rb new file mode 100644 index 00000000..3c4ab61b --- /dev/null +++ b/spec/data/plugins/v6/platform.rb @@ -0,0 +1,28 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "platform", "platform_version", "platform_family" + +require_plugin "#{os}::platform" + +platform os unless attribute?("platform") + +platform_version os_version unless attribute?("platform_version") + +platform_family platform unless attribute?("platform_family") + diff --git a/spec/data/plugins/v6/python.rb b/spec/data/plugins/v6/python.rb new file mode 100644 index 00000000..1b15f941 --- /dev/null +++ b/spec/data/plugins/v6/python.rb @@ -0,0 +1,37 @@ +# +# Author:: Thom May (<thom@clearairturbulence.org>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages/python" + +require_plugin "languages" + +output = nil + +python = Mash.new + +status, stdout, stderr = run_command(:no_status_check => true, :command => "python -c \"import sys; print sys.version\"") + +if status == 0 + output = stdout.split + python[:version] = output[0] + if output.length >= 6 + python[:builddate] = "%s %s %s %s" % [output[2],output[3],output[4],output[5].gsub!(/\)/,'')] + end + + languages[:python] = python if python[:version] and python[:builddate] +end diff --git a/spec/data/plugins/v6/rackspace.rb b/spec/data/plugins/v6/rackspace.rb new file mode 100644 index 00000000..5f86866f --- /dev/null +++ b/spec/data/plugins/v6/rackspace.rb @@ -0,0 +1,109 @@ +# +# Author:: Cary Penniman (<cary@rightscale.com>) +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provides "rackspace" + +require_plugin "kernel" +require_plugin "network" + +# Checks for matching rackspace kernel name +# +# === Return +# true:: If kernel name matches +# false:: Otherwise +def has_rackspace_kernel? + kernel[:release].split('-').last.eql?("rscloud") +end + +# Checks for rackspace provider attribute +# +# === Return +# true:: If rackspace provider attribute found +# false:: Otherwise +def has_rackspace_metadata? + status, stdout, stderr = run_command(:no_status_check => true, :command => "xenstore-read vm-data/provider_data/provider") + if status == 0 + stdout.strip.downcase == 'rackspace' + end +rescue Ohai::Exceptions::Exec + false +end + +# Identifies the rackspace cloud +# +# === Return +# true:: If the rackspace cloud can be identified +# false:: Otherwise +def looks_like_rackspace? + hint?('rackspace') || has_rackspace_metadata? || has_rackspace_kernel? +end + +# Names rackspace ip address +# +# === Parameters +# name<Symbol>:: Use :public_ip or :private_ip +# eth<Symbol>:: Interface name of public or private ip +def get_ip_address(name, eth) + network[:interfaces][eth][:addresses].each do |key, info| + if info['family'] == 'inet' + rackspace[name] = key + break # break when we found an address + end + end +end + +# Names rackspace ipv6 address for interface +# +# === Parameters +# name<Symbol>:: Use :public_ip or :private_ip +# eth<Symbol>:: Interface name of public or private ip +def get_global_ipv6_address(name, eth) + network[:interfaces][eth][:addresses].each do |key, info| + # check if we got an ipv6 address and if its in global scope + if info['family'] == 'inet6' && info['scope'] == 'Global' + rackspace[name] = key + break # break when we found an address + end + end +end + +# Get the rackspace region +# +def get_region() + status, stdout, stderr = run_command(:no_status_check => true, :command => "xenstore-ls vm-data/provider_data") + if status == 0 + stdout.split("\n").each do |line| + rackspace[:region] = line.split[2].delete('\"') if line =~ /^region/ + end + end +rescue Ohai::Exceptions::Exec + Ohai::Log.debug("Unable to find xenstore-ls, cannot capture region information for Rackspace cloud") +end + +# Adds rackspace Mash +if looks_like_rackspace? + rackspace Mash.new + get_ip_address(:public_ip, :eth0) + get_ip_address(:private_ip, :eth1) + get_region() + # public_ip + private_ip are deprecated in favor of public_ipv4 and local_ipv4 to standardize. + rackspace[:public_ipv4] = rackspace[:public_ip] + get_global_ipv6_address(:public_ipv6, :eth0) + rackspace[:public_hostname] = "#{rackspace[:public_ip].gsub('.','-')}.static.cloud-ips.com" + rackspace[:local_ipv4] = rackspace[:private_ip] + get_global_ipv6_address(:local_ipv6, :eth1) + rackspace[:local_hostname] = hostname +end diff --git a/spec/data/plugins/v6/root_group.rb b/spec/data/plugins/v6/root_group.rb new file mode 100644 index 00000000..c74bcb0e --- /dev/null +++ b/spec/data/plugins/v6/root_group.rb @@ -0,0 +1,28 @@ +# +# Author:: Joseph Anthony Pasquale Holsten (<joseph@josephholsten.com>) +# Copyright:: Copyright (c) 2013 Joseph Anthony Pasquale Holsten +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +provides 'root_group' + +case ::RbConfig::CONFIG['host_os'] +when /mswin|mingw32|windows/ + # TODO: OHAI-491 + # http://tickets.opscode.com/browse/OHAI-491 + # The windows implementation of this plugin has been removed because of + # performance considerations (see: OHAI-490). +else + root_group Etc.getgrgid(Etc.getpwnam('root').gid).name +end diff --git a/spec/data/plugins/v6/ruby.rb b/spec/data/plugins/v6/ruby.rb new file mode 100644 index 00000000..a54de8e8 --- /dev/null +++ b/spec/data/plugins/v6/ruby.rb @@ -0,0 +1,75 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "languages/ruby" + +require_plugin "languages" + + +def run_ruby(command) + cmd = "ruby -e \"require 'rbconfig'; #{command}\"" + status, stdout, stderr = run_command(:no_status_check => true, :command => cmd) + stdout.strip +end + + +languages[:ruby] = Mash.new + +values = { + :platform => "RUBY_PLATFORM", + :version => "RUBY_VERSION", + :release_date => "RUBY_RELEASE_DATE", + :target => "::Config::CONFIG['target']", + :target_cpu => "::Config::CONFIG['target_cpu']", + :target_vendor => "::Config::CONFIG['target_vendor']", + :target_os => "::Config::CONFIG['target_os']", + :host => "::Config::CONFIG['host']", + :host_cpu => "::Config::CONFIG['host_cpu']", + :host_os => "::Config::CONFIG['host_os']", + :host_vendor => "::Config::CONFIG['host_vendor']", + :bin_dir => "::Config::CONFIG['bindir']", + :ruby_bin => "::File.join(::Config::CONFIG['bindir'], ::Config::CONFIG['ruby_install_name'])" +} + +# Create a query string from above hash +env_string = "" +values.keys.each do |v| + env_string << "#{v}=\#{#{values[v]}}," +end + +# Query the system ruby +result = run_ruby "puts %Q(#{env_string})" + +# Parse results to plugin hash +result.split(',').each do |entry| + key, value = entry.split('=') + languages[:ruby][key.to_sym] = value || "" +end + +# Perform one more (conditional) query +bin_dir = languages[:ruby][:bin_dir] +ruby_bin = languages[:ruby][:ruby_bin] +gem_binaries = [ + run_ruby("require 'rubygems'; puts ::Gem.default_exec_format % 'gem'"), + "gem" +].map {|bin| ::File.join(bin_dir, bin)} +gem_binary = gem_binaries.find {|bin| ::File.exists? bin } +if gem_binary + languages[:ruby][:gems_dir] = run_ruby "puts %x{#{ruby_bin} #{gem_binary} env gemdir}.chomp!" + languages[:ruby][:gem_bin] = gem_binary +end diff --git a/spec/data/plugins/v6/sigar/cpu.rb b/spec/data/plugins/v6/sigar/cpu.rb new file mode 100644 index 00000000..89cb14c9 --- /dev/null +++ b/spec/data/plugins/v6/sigar/cpu.rb @@ -0,0 +1,40 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "sigar" + +sigar = Sigar.new + +provides "cpu" + +cpuinfo = Mash.new +ix = 0 + +sigar.cpu_info_list.each do |info| + current_cpu = ix.to_s + ix += 1 + cpuinfo[current_cpu] = Mash.new + cpuinfo[current_cpu]["vendor_id"] = info.vendor + cpuinfo[current_cpu]["model"] = info.model + cpuinfo[current_cpu]["mhz"] = info.mhz.to_s + cpuinfo[current_cpu]["cache_size"] = info.cache_size.to_s + cpuinfo[:total] = info.total_cores + cpuinfo[:real] = info.total_sockets +end + +cpu cpuinfo diff --git a/spec/data/plugins/v6/sigar/filesystem.rb b/spec/data/plugins/v6/sigar/filesystem.rb new file mode 100644 index 00000000..283414c1 --- /dev/null +++ b/spec/data/plugins/v6/sigar/filesystem.rb @@ -0,0 +1,47 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "filesystem" + +require "sigar" + +fs = Mash.new + +sigar = Sigar.new + +sigar.file_system_list.each do |fsys| + filesystem = fsys.dev_name + fs[filesystem] = Mash.new + fs[filesystem][:mount] = fsys.dir_name + fs[filesystem][:fs_type] = fsys.sys_type_name + fs[filesystem][:mount_options] = fsys.options + begin + usage = sigar.file_system_usage(fsys.dir_name) + fs[filesystem][:kb_size] = (usage.total / 1024).to_s + fs[filesystem][:kb_used] = ((usage.total - usage.free) / 1024).to_s + fs[filesystem][:kb_available] = (usage.free / 1024).to_s + fs[filesystem][:percent_used] = (usage.use_percent * 100).to_s + '%' + rescue SystemExit => e + raise + rescue Exception => e + #e.g. floppy or cdrom drive + end +end + +# Set the filesystem data +filesystem fs diff --git a/spec/data/plugins/v6/sigar/hostname.rb b/spec/data/plugins/v6/sigar/hostname.rb new file mode 100644 index 00000000..5c563293 --- /dev/null +++ b/spec/data/plugins/v6/sigar/hostname.rb @@ -0,0 +1,28 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'sigar' + +provides "hostname", "fqdn" + +sigar = Sigar.new + +hostname sigar.net_info.host_name + +fqdn sigar.fqdn + diff --git a/spec/data/plugins/v6/sigar/memory.rb b/spec/data/plugins/v6/sigar/memory.rb new file mode 100644 index 00000000..9c3fee48 --- /dev/null +++ b/spec/data/plugins/v6/sigar/memory.rb @@ -0,0 +1,36 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "sigar" + +sigar = Sigar.new + +provides "memory" + +memory Mash.new +memory[:swap] = Mash.new + +mem = sigar.mem +swap = sigar.swap + +memory[:total] = (mem.total / 1024).to_s + "kB" +memory[:free] = (mem.free / 1024).to_s + "kB" +memory[:used] = (mem.used / 1024).to_s + "kB" +memory[:swap][:total] = (swap.total / 1024).to_s + "kB" +memory[:swap][:free] = (swap.free / 1024).to_s + "kB" +memory[:swap][:used] = (swap.used / 1024).to_s + "kB" diff --git a/spec/data/plugins/v6/sigar/network.rb b/spec/data/plugins/v6/sigar/network.rb new file mode 100644 index 00000000..2b5c0265 --- /dev/null +++ b/spec/data/plugins/v6/sigar/network.rb @@ -0,0 +1,102 @@ +# +# Author:: Matthew Kent (<mkent@magoazul.com>) +# Copyright:: Copyright (c) 2009 Matthew Kent +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#http://github.com/mdkent/ohai/commit/92f51aa18b6add9682510a87dcf94835ea72b04d + +require "sigar" + +sigar = Sigar.new + +provides "network", "counters/network" + +ninfo = sigar.net_info + +network[:default_interface] = ninfo.default_gateway_interface + +network[:default_gateway] = ninfo.default_gateway + +def encaps_lookup(encap) + return "Loopback" if encap.eql?("Local Loopback") + return "PPP" if encap.eql?("Point-to-Point Protocol") + return "SLIP" if encap.eql?("Serial Line IP") + return "VJSLIP" if encap.eql?("VJ Serial Line IP") + return "IPIP" if encap.eql?("IPIP Tunnel") + return "6to4" if encap.eql?("IPv6-in-IPv4") + encap +end + +iface = Mash.new + +net_counters = Mash.new + +sigar.net_interface_list.each do |cint| + iface[cint] = Mash.new + if cint =~ /^(\w+)(\d+.*)/ + iface[cint][:type] = $1 + iface[cint][:number] = $2 + end + ifconfig = sigar.net_interface_config(cint) + iface[cint][:encapsulation] = encaps_lookup(ifconfig.type) + iface[cint][:addresses] = Mash.new + # Backwards compat: loopback has no hwaddr + if (ifconfig.flags & Sigar::IFF_LOOPBACK) == 0 + iface[cint][:addresses][ifconfig.hwaddr] = { "family" => "lladdr" } + end + if ifconfig.address != "0.0.0.0" + iface[cint][:addresses][ifconfig.address] = { "family" => "inet" } + # Backwards compat: no broadcast on tunnel or loopback dev + if (((ifconfig.flags & Sigar::IFF_POINTOPOINT) == 0) && + ((ifconfig.flags & Sigar::IFF_LOOPBACK) == 0)) + iface[cint][:addresses][ifconfig.address]["broadcast"] = ifconfig.broadcast + end + iface[cint][:addresses][ifconfig.address]["netmask"] = ifconfig.netmask + end + iface[cint][:flags] = Sigar.net_interface_flags_to_s(ifconfig.flags).split(' ') + iface[cint][:mtu] = ifconfig.mtu.to_s + iface[cint][:queuelen] = ifconfig.tx_queue_len.to_s + if ifconfig.prefix6_length != 0 + iface[cint][:addresses][ifconfig.address6] = { "family" => "inet6" } + iface[cint][:addresses][ifconfig.address6]["prefixlen"] = ifconfig.prefix6_length.to_s + iface[cint][:addresses][ifconfig.address6]["scope"] = Sigar.net_scope_to_s(ifconfig.scope6) + end + net_counters[cint] = Mash.new unless net_counters[cint] + if (!cint.include?(":")) + ifstat = sigar.net_interface_stat(cint) + net_counters[cint][:rx] = { "packets" => ifstat.rx_packets.to_s, "errors" => ifstat.rx_errors.to_s, + "drop" => ifstat.rx_dropped.to_s, "overrun" => ifstat.rx_overruns.to_s, + "frame" => ifstat.rx_frame.to_s, "bytes" => ifstat.rx_bytes.to_s } + net_counters[cint][:tx] = { "packets" => ifstat.tx_packets.to_s, "errors" => ifstat.tx_errors.to_s, + "drop" => ifstat.tx_dropped.to_s, "overrun" => ifstat.tx_overruns.to_s, + "carrier" => ifstat.tx_carrier.to_s, "collisions" => ifstat.tx_collisions.to_s, + "bytes" => ifstat.tx_bytes.to_s } + end +end + +begin + sigar.arp_list.each do |arp| + next unless iface[arp.ifname] # this should never happen + iface[arp.ifname][:arp] = Mash.new unless iface[arp.ifname][:arp] + iface[arp.ifname][:arp][arp.address] = arp.hwaddr + end +rescue + #64-bit AIX for example requires 64-bit caller +end + +counters[:network][:interfaces] = net_counters + +network["interfaces"] = iface diff --git a/spec/data/plugins/v6/sigar/network_route.rb b/spec/data/plugins/v6/sigar/network_route.rb new file mode 100644 index 00000000..b13c1235 --- /dev/null +++ b/spec/data/plugins/v6/sigar/network_route.rb @@ -0,0 +1,54 @@ +# +# Author:: Toomas Pelberg (<toomas.pelberg@playtech.com>) +# Copyright:: Copyright (c) 2011 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "sigar" +require_plugin "network" + +provides "network" + +def flags(flags) + f = "" + if (flags & Sigar::RTF_UP) != 0 + f += "U" + end + if (flags & Sigar::RTF_GATEWAY) != 0 + f += "G" + end + if (flags & Sigar::RTF_HOST) != 0 + f += "H" + end + f +end + +# From sigar: include/sigar.h sigar_net_route_t +SIGAR_ROUTE_METHODS = [:destination, :gateway, :mask, :flags, :refcnt, :use, :metric, :mtu, :window, :irtt, :ifname] + +sigar=Sigar.new +sigar.net_route_list.each do |route| + next unless network[:interfaces][route.ifname] # this should never happen + network[:interfaces][route.ifname][:route] = Mash.new unless network[:interfaces][route.ifname][:route] + route_data={} + SIGAR_ROUTE_METHODS.each do |m| + if(m == :flags) + route_data[m]=flags(route.send(m)) + else + route_data[m]=route.send(m) + end + end + network[:interfaces][route.ifname][:route][route.destination] = route_data +end diff --git a/spec/data/plugins/v6/sigar/platform.rb b/spec/data/plugins/v6/sigar/platform.rb new file mode 100644 index 00000000..1fedb564 --- /dev/null +++ b/spec/data/plugins/v6/sigar/platform.rb @@ -0,0 +1,26 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "sigar" + +provides "platform", "platform_version" + +sys = Sigar.new.sys_info + +platform sys.name.downcase +platform_version sys.version diff --git a/spec/data/plugins/v6/sigar/uptime.rb b/spec/data/plugins/v6/sigar/uptime.rb new file mode 100644 index 00000000..5d2923d1 --- /dev/null +++ b/spec/data/plugins/v6/sigar/uptime.rb @@ -0,0 +1,27 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "sigar" + +sigar = Sigar.new + +provides "uptime", "uptime_seconds" + +uptime = sigar.uptime.uptime +uptime_seconds uptime.to_i * 1000 +uptime self._seconds_to_human(uptime.to_i) diff --git a/spec/data/plugins/v6/solaris2/cpu.rb b/spec/data/plugins/v6/solaris2/cpu.rb new file mode 100644 index 00000000..35641838 --- /dev/null +++ b/spec/data/plugins/v6/solaris2/cpu.rb @@ -0,0 +1,33 @@ +#$ psrinfo -v +#Status of virtual processor 0 as of: 01/11/2009 23:31:55 +# on-line since 05/29/2008 15:05:28. +# The i386 processor operates at 2660 MHz, +# and has an i387 compatible floating point processor. +#Status of virtual processor 1 as of: 01/11/2009 23:31:55 +# on-line since 05/29/2008 15:05:30. +# The i386 processor operates at 2660 MHz, +# and has an i387 compatible floating point processor. +#Status of virtual processor 2 as of: 01/11/2009 23:31:55 +# on-line since 05/29/2008 15:05:30. +# The i386 processor operates at 2660 MHz, +# and has an i387 compatible floating point processor. +#Status of virtual processor 3 as of: 01/11/2009 23:31:55 +# on-line since 05/29/2008 15:05:30. +# The i386 processor operates at 2660 MHz, +# and has an i387 compatible floating point processor. +#Status of virtual processor 4 as of: 01/11/2009 23:31:55 +# on-line since 05/29/2008 15:05:30. +# The i386 processor operates at 2660 MHz, +# and has an i387 compatible floating point processor. +#Status of virtual processor 5 as of: 01/11/2009 23:31:55 +# on-line since 05/29/2008 15:05:30. +# The i386 processor operates at 2660 MHz, +# and has an i387 compatible floating point processor. +#Status of virtual processor 6 as of: 01/11/2009 23:31:55 +# on-line since 05/29/2008 15:05:30. +# The i386 processor operates at 2660 MHz, +# and has an i387 compatible floating point processor. +#Status of virtual processor 7 as of: 01/11/2009 23:31:55 +# on-line since 05/29/2008 15:05:30. +# The i386 processor operates at 2660 MHz, +# and has an i387 compatible floating point processor. diff --git a/spec/data/plugins/v6/solaris2/dmi.rb b/spec/data/plugins/v6/solaris2/dmi.rb new file mode 100644 index 00000000..87d00fb3 --- /dev/null +++ b/spec/data/plugins/v6/solaris2/dmi.rb @@ -0,0 +1,176 @@ +# +# Author:: Kurt Yoder (ktyopscode@yoderhome.com) +# Copyright:: Copyright (c) 2010 Kurt Yoder +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require_plugin "dmi" + +# if we already have a "dmi" with keys (presumably from dmidecode), don't try smbios +# note that a single key just means dmidecode exited with its version +if (dmi.class.to_s == 'Mash') and (dmi.keys.length > 1) + Ohai::Log.debug('skipping smbios output, since DMI information has already been provided') + return +end + +dmi Mash.new + +# bad Solaris shows strings defined by system instead of SMB IDs +# this is what the *real* IDs are: +# pulled from http://src.opensolaris.org/source/xref/nwam/nwam1/usr/src/uts/common/sys/smbios.h +smb_to_id = { + 'SMB_TYPE_BIOS' => 0, # BIOS information (R) + 'SMB_TYPE_SYSTEM' => 1, # system information (R) + 'SMB_TYPE_BASEBOARD' => 2, # base board + 'SMB_TYPE_CHASSIS' => 3, # system enclosure or chassis (R) + 'SMB_TYPE_PROCESSOR' => 4, # processor (R) + 'SMB_TYPE_MEMCTL' => 5, # memory controller (O) + 'SMB_TYPE_MEMMOD' => 6, # memory module (O) + 'SMB_TYPE_CACHE' => 7, # processor cache (R) + 'SMB_TYPE_PORT' => 8, # port connector + 'SMB_TYPE_SLOT' => 9, # upgradeable system slot (R) + 'SMB_TYPE_OBDEVS' => 10, # on-board devices + 'SMB_TYPE_OEMSTR' => 11, # OEM string table + 'SMB_TYPE_SYSCONFSTR' => 12, # system configuration string table + 'SMB_TYPE_LANG' => 13, # BIOS language information + 'SMB_TYPE_GROUP' => 14, # group associations + 'SMB_TYPE_EVENTLOG' => 15, # system event log + 'SMB_TYPE_MEMARRAY' => 16, # physical memory array (R) + 'SMB_TYPE_MEMDEVICE' => 17, # memory device (R) + 'SMB_TYPE_MEMERR32' => 18, # 32-bit memory error information + 'SMB_TYPE_MEMARRAYMAP' => 19, # memory array mapped address (R) + 'SMB_TYPE_MEMDEVICEMAP' => 20, # memory device mapped address (R) + 'SMB_TYPE_POINTDEV' => 21, # built-in pointing device + 'SMB_TYPE_BATTERY' => 22, # portable battery + 'SMB_TYPE_RESET' => 23, # system reset settings + 'SMB_TYPE_SECURITY' => 24, # hardware security settings + 'SMB_TYPE_POWERCTL' => 25, # system power controls + 'SMB_TYPE_VPROBE' => 26, # voltage probe + 'SMB_TYPE_COOLDEV' => 27, # cooling device + 'SMB_TYPE_TPROBE' => 28, # temperature probe + 'SMB_TYPE_IPROBE' => 29, # current probe + 'SMB_TYPE_OOBRA' => 30, # out-of-band remote access facility + 'SMB_TYPE_BIS' => 31, # boot integrity services + 'SMB_TYPE_BOOT' => 32, # system boot status (R) + 'SMB_TYPE_MEMERR64' => 33, # 64-bit memory error information + 'SMB_TYPE_MGMTDEV' => 34, # management device + 'SMB_TYPE_MGMTDEVCP' => 35, # management device component + 'SMB_TYPE_MGMTDEVDATA' => 36, # management device threshold data + 'SMB_TYPE_MEMCHAN' => 37, # memory channel + 'SMB_TYPE_IPMIDEV' => 38, # IPMI device information + 'SMB_TYPE_POWERSUP' => 39, # system power supply + 'SMB_TYPE_INACTIVE' => 126, # inactive table entry + 'SMB_TYPE_EOT' => 127, # end of table + 'SMB_TYPE_OEM_LO' => 128, # start of OEM-specific type range + 'SUN_OEM_EXT_PROCESSOR' => 132, # processor extended info + 'SUN_OEM_PCIEXRC' => 138, # PCIE RootComplex/RootPort info + 'SUN_OEM_EXT_MEMARRAY' => 144, # phys memory array extended info + 'SUN_OEM_EXT_MEMDEVICE' => 145, # memory device extended info + 'SMB_TYPE_OEM_HI' => 256, # end of OEM-specific type range +} + +# all output lines should fall within one of these patterns +header_type_line = /^ID\s+SIZE\s+TYPE/ +header_information_line = /^(\d+)\s+(\d+)\s+(\S+)\s+\(([^\)]+)\)/ +blank_line = /^\s*$/ +data_key_value_line = /^ ([^:]+): (.*)/ +data_key_only_line = /^ (\S.*)(:\s*)?$/ +extended_data_line = /^\t(\S+) \((.+)\)/ + +dmi_record = nil +field = nil + +popen4("smbios") do |pid, stdin, stdout, stderr| + stdin.close + + # ==== EXAMPLE: ==== + # ID SIZE TYPE + # 0 40 SMB_TYPE_BIOS (BIOS information) + # + # Vendor: HP + # Version String: 2.16 + # ... similar lines trimmed + # Characteristics: 0x7fc9da80 + # SMB_BIOSFL_PCI (PCI is supported) + # ... similar lines trimmed + # note the second level of indentation is via a *tab* + stdout.each do |raw_line| + next if header_type_line.match(raw_line) + next if blank_line.match(raw_line) + + # remove/replace any characters that don't fall inside permissible ASCII range, or whitespace + line = raw_line.gsub(/[^\x20-\x7E\n\t\r]/, '.') + if (line != raw_line) + Ohai::Log.debug("converted characters from line:\n#{raw_line}") + end + + if header_information = header_information_line.match(line) + dmi_record = {} + + # look up SMB ID + if smb_to_id.has_key?(header_information[3]) + dmi_record[:type] = DMI.id_lookup(smb_to_id[header_information[3]]) + + else + dmi_record[:type] = header_information[3].downcase + Ohai::Log.debug("unrecognized header type; falling back to #{dmi_record[:type]}") + end + + dmi[dmi_record[:type]] = Mash.new unless dmi.has_key?(dmi_record[:type]) + dmi[dmi_record[:type]][:all_records] = [] unless dmi[dmi_record[:type]].has_key?(:all_records) + dmi_record[:position] = dmi[dmi_record[:type]][:all_records].length + dmi[dmi_record[:type]][:all_records].push(Mash.new) + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:record_id] = header_information[1] + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:size] = header_information[2] + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:application_identifier] = header_information[4] + field = nil + + elsif data = data_key_value_line.match(line) + if dmi_record == nil + Ohai::Log.debug("unexpected data line found before header; discarding:\n#{line}") + next + end + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][data[1]] = data[2] + field = data[1] + + elsif data = data_key_only_line.match(line) + if dmi_record == nil + Ohai::Log.debug("unexpected data line found before header; discarding:\n#{line}") + next + end + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][data[1]] = '' + field = data[1] + + elsif extended_data = extended_data_line.match(line) + if dmi_record == nil + Ohai::Log.debug("unexpected extended data line found before header; discarding:\n#{line}") + next + end + if field == nil + Ohai::Log.debug("unexpected extended data line found outside data section; discarding:\n#{line}") + next + end + # overwrite "raw" value with a new Mash + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field] = Mash.new unless dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field].class.to_s == 'Mash' + dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field][extended_data[1]] = extended_data[2] + + else + Ohai::Log.debug("unrecognized output line; discarding:\n#{line}") + + end + end +end + +DMI.convenience_keys(dmi) diff --git a/spec/data/plugins/v6/solaris2/filesystem.rb b/spec/data/plugins/v6/solaris2/filesystem.rb new file mode 100644 index 00000000..ddc7d7a9 --- /dev/null +++ b/spec/data/plugins/v6/solaris2/filesystem.rb @@ -0,0 +1,101 @@ +# +# Author:: Kurt Yoder (ktyopscode@yoderhome.com) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "filesystem" + +fs = Mash.new + +# Grab filesystem data from df +popen4("df -Pka") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^Filesystem\s+kbytes/ + next + when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/ + filesystem = $1 + fs[filesystem] = Mash.new + fs[filesystem][:kb_size] = $2 + fs[filesystem][:kb_used] = $3 + fs[filesystem][:kb_available] = $4 + fs[filesystem][:percent_used] = $5 + fs[filesystem][:mount] = $6 + end + end +end + +# Grab file system type from df (must be done separately) +popen4("df -na") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + next unless (line =~ /^(.+?)\s*: (\S+)\s*$/) + mount = $1 + fs.each { |filesystem,fs_attributes| + next unless (fs_attributes[:mount] == mount) + fs[filesystem][:fs_type] = $2 + } + end +end + +# Grab mount information from /bin/mount +popen4("mount") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + next unless (line =~ /^(.+?) on (.+?) (.+?) on (.+?)$/) + filesystem = $2 + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem][:mount] = $1 + fs[filesystem][:mount_time] = $4 # $4 must come before "split", else it becomes nil + fs[filesystem][:mount_options] = $3.split("/") + end +end + +# Grab any zfs data from "zfs get" +zfs = Mash.new +popen4("zfs get -p -H all") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + next unless (line =~ /^([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)$/) + filesystem = $1 + zfs[filesystem] = Mash.new unless zfs.has_key?(filesystem) + zfs[filesystem][:values] = Mash.new unless zfs[filesystem].has_key?('values') + zfs[filesystem][:sources] = Mash.new unless zfs[filesystem].has_key?('sources') + zfs[filesystem][:values][$2] = $3 + zfs[filesystem][:sources][$2] = $4.chomp + end +end +zfs.each { |filesystem, attributes| + fs[filesystem] = Mash.new unless fs.has_key?(filesystem) + fs[filesystem][:fs_type] = 'zfs' + fs[filesystem][:mount] = attributes[:values][:mountpoint] if attributes[:values].has_key?('mountpoint') + fs[filesystem][:zfs_values] = attributes[:values] + fs[filesystem][:zfs_sources] = attributes[:sources] + # find all zfs parents + parents = filesystem.split('/') + zfs_parents = [] + (0 .. parents.length - 1).to_a.each { |parent_indexes| + next_parent = parents[0 .. parent_indexes].join('/') + zfs_parents.push(next_parent) + } + zfs_parents.pop + fs[filesystem][:zfs_parents] = zfs_parents + fs[filesystem][:zfs_zpool] = (zfs_parents.length == 0) +} + +# Set the filesystem data +filesystem fs diff --git a/spec/data/plugins/v6/solaris2/hostname.rb b/spec/data/plugins/v6/solaris2/hostname.rb new file mode 100644 index 00000000..9c1b4272 --- /dev/null +++ b/spec/data/plugins/v6/solaris2/hostname.rb @@ -0,0 +1,34 @@ +# +# Author:: Benjamin Black (<nostromo@gmail.com>) +# Author:: Daniel DeLeo <dan@kallistec.com> +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# Copyright:: Copyright (c) 2009 Daniel DeLeo +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +require 'socket' + +provides "hostname", "fqdn" + +hostname from("hostname") + +fqdn_lookup = Socket.getaddrinfo(hostname, nil, nil, nil, nil, Socket::AI_CANONNAME).first[2] + +if fqdn_lookup.split('.').length > 1 + # we recieved an fqdn + fqdn fqdn_lookup +else + # default to assembling one + fqdn(from("hostname") + "." + from("domainname")) +end diff --git a/spec/data/plugins/v6/solaris2/kernel.rb b/spec/data/plugins/v6/solaris2/kernel.rb new file mode 100644 index 00000000..e981f1f4 --- /dev/null +++ b/spec/data/plugins/v6/solaris2/kernel.rb @@ -0,0 +1,40 @@ +# +# Author:: Benjamin Black (<nostromo@gmail.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "kernel/os" + +kernel[:os] = from("uname -s") + +modules = Mash.new + +popen4("modinfo") do |pid, stdin, stdout, stderr| + stdin.close + + # EXAMPLE: + # Id Loadaddr Size Info Rev Module Name + # 6 1180000 4623 1 1 specfs (filesystem for specfs) + module_description = /[\s]*([\d]+)[\s]+([a-f\d]+)[\s]+([a-f\d]+)[\s]+(?:[\-\d]+)[\s]+(?:[\d]+)[\s]+([\S]+)[\s]+\((.+)\)$/ + stdout.each do |line| + if mod = module_description.match(line) + modules[mod[4]] = { :id => mod[1].to_i, :loadaddr => mod[2], :size => mod[3].to_i(16), :description => mod[5]} + end + end +end + +kernel[:modules] = modules + diff --git a/spec/data/plugins/v6/solaris2/network.rb b/spec/data/plugins/v6/solaris2/network.rb new file mode 100644 index 00000000..6a9da9bb --- /dev/null +++ b/spec/data/plugins/v6/solaris2/network.rb @@ -0,0 +1,160 @@ +# +# Author:: Benjamin Black (<nostromo@gmail.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# EXAMPLE SOLARIS IFCONFIG OUTPUT; CURRENTLY, ONLY SIMPLE STUFF IS SUPPORTED (E.G., NO TUNNELS) +# DEAR SUN: YOU GET AN F FOR YOUR IFCONFIG +#lo0:3: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index 1 +# inet 127.0.0.1 netmask ff000000 +#e1000g0:3: flags=201000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4,CoS> mtu 1500 index 3 +# inet 72.2.115.28 netmask ffffff80 broadcast 72.2.115.127 +#e1000g2:1: flags=201000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4,CoS> mtu 1500 index 4 +# inet 10.2.115.28 netmask ffffff80 broadcast 10.2.115.127 +# inet6 2001:0db8:3c4d:55:a00:20ff:fe8e:f3ad/64 +#ip.tun0: flags=2200851<UP,POINTOPOINT,RUNNING,MULTICAST,NONUD,IPv6> mtu 1480 index 3 +# inet tunnel src 109.146.85.57 tunnel dst 109.146.85.212 +# tunnel security settings --> use 'ipsecconf -ln -i ip.tun1' +# tunnel hop limit 60 +# inet6 fe80::6d92:5539/10 --> fe80::6d92:55d4 +#ip.tun0:1: flags=2200851<UP,POINTOPOINT,RUNNING,MULTICAST,NONUD,IPv6> mtu 1480 index 3 +# inet6 2::45/128 --> 2::46 +#lo0: flags=1000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4> mtu 8232 index 1 +# inet 127.0.0.1 netmask ff000000 +#eri0: flags=1004843<UP,BROADCAST,RUNNING,MULTICAST,DHCP,IPv4> mtu 1500 \ +#index 2 +# inet 172.17.128.208 netmask ffffff00 broadcast 172.17.128.255 +#ip6.tun0: flags=10008d1<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST,IPv4> \ +#mtu 1460 +# index 3 +# inet6 tunnel src fe80::1 tunnel dst fe80::2 +# tunnel security settings --> use 'ipsecconf -ln -i ip.tun1' +# tunnel hop limit 60 tunnel encapsulation limit 4 +# inet 10.0.0.208 --> 10.0.0.210 netmask ff000000 +#qfe1: flags=2000841<UP,RUNNING,MULTICAST,IPv6> mtu 1500 index 3 +# usesrc vni0 +# inet6 fe80::203:baff:fe17:4be0/10 +# ether 0:3:ba:17:4b:e0 +#vni0: flags=2002210041<UP,RUNNING,NOXMIT,NONUD,IPv6,VIRTUAL> mtu 0 +# index 5 +# srcof qfe1 +# inet6 fe80::203:baff:fe17:4444/128 + +provides "network" + +require 'scanf' + +def encaps_lookup(ifname) + return "Ethernet" if ifname.eql?("e1000g") + return "Ethernet" if ifname.eql?("eri") + return "Ethernet" if ifname.eql?("net") + return "Loopback" if ifname.eql?("lo") + "Unknown" +end + +def arpname_to_ifname(iface, arpname) + iface.keys.each do |ifn| + return ifn if ifn.split(':')[0].eql?(arpname) + end + + nil +end + +iface = Mash.new +popen4("ifconfig -a") do |pid, stdin, stdout, stderr| + stdin.close + cint = nil + stdout.each do |line| + if line =~ /^([0-9a-zA-Z\.\:\-]+): \S+ mtu (\d+) index (\d+)/ + cint = $1 + iface[cint] = Mash.new unless iface[cint] + iface[cint][:mtu] = $2 + iface[cint][:index] = $3 + if line =~ / flags\=\d+\<((ADDRCONF|ANYCAST|BROADCAST|CoS|DEPRECATED|DHCP|DUPLICATE|FAILED|FIXEDMTU|INACTIVE|L3PROTECT|LOOPBACK|MIP|MULTI_BCAST|MULTICAST|NOARP|NOFAILOVER|NOLOCAL|NONUD|NORTEXCH|NOXMIT|OFFLINE|POINTOPOINT|PREFERRED|PRIVATE|ROUTER|RUNNING|STANDBY|TEMPORARY|UNNUMBERED|UP|VIRTUAL|XRESOLV|IPv4|IPv6|,)+)\>\s/ + flags = $1.split(',') + else + flags = Array.new + end + iface[cint][:flags] = flags.flatten + if cint =~ /^(\w+)(\d+.*)/ + iface[cint][:type] = $1 + iface[cint][:number] = $2 + iface[cint][:encapsulation] = encaps_lookup($1) + end + end + if line =~ /\s+inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) netmask (([0-9a-f]){1,8})\s*$/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => $2.scanf('%2x'*4)*"."} + end + if line =~ /\s+inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) netmask (([0-9a-f]){1,8}) broadcast (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "inet", "netmask" => $2.scanf('%2x'*4)*".", "broadcast" => $4 } + end + if line =~ /\s+inet6 ([a-f0-9\:]+)(\s*|(\%[a-z0-9]+)\s*)\/(\d+)\s*$/ + iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] + iface[cint][:addresses][$1] = { "family" => "inet6", "prefixlen" => $4 } + end + end +end + +popen4("arp -an") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /([0-9a-zA-Z]+)\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+(\w+)\s+([a-zA-Z0-9\.\:\-]+)/ + next unless iface[arpname_to_ifname(iface, $1)] # this should never happen, except on solaris because sun hates you. + iface[arpname_to_ifname(iface, $1)][:arp] = Mash.new unless iface[arpname_to_ifname(iface, $1)][:arp] + iface[arpname_to_ifname(iface, $1)][:arp][$2] = $5 + end + end +end + +iface.keys.each do |ifn| + iaddr = nil + if iface[ifn][:encapsulation].eql?("Ethernet") + iface[ifn][:addresses].keys.each do |addr| + if iface[ifn][:addresses][addr]["family"].eql?("inet") + iaddr = addr + break + end + end + if iface[ifn][:arp] + iface[ifn][:arp].keys.each do |addr| + if addr.eql?(iaddr) + iface[ifn][:addresses][iface[ifn][:arp][iaddr]] = { "family" => "lladdr" } + break + end + end + end + end +end + +network[:interfaces] = iface + +popen4("route -n get default") do |pid, stdin, stdout, stderr| + stdin.close + route_get = stdout.read + matches = /interface: (\S+)/.match(route_get) + if matches + Ohai::Log.debug("found gateway device: #{$1}") + network[:default_interface] = matches[1] + end + matches = /gateway: (\S+)/.match(route_get) + if matches + Ohai::Log.debug("found gateway: #{$1}") + network[:default_gateway] = matches[1] + end +end + diff --git a/spec/data/plugins/v6/solaris2/platform.rb b/spec/data/plugins/v6/solaris2/platform.rb new file mode 100644 index 00000000..5f21e00a --- /dev/null +++ b/spec/data/plugins/v6/solaris2/platform.rb @@ -0,0 +1,61 @@ +# +# Author:: Benjamin Black (<nostromo@gmail.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "platform", "platform_version", "platform_build" + +if File.exists?("/sbin/uname") + uname_exec = "/sbin/uname" +else + uname_exec = "uname" +end + +popen4("#{uname_exec} -X") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^Release =\s+(.+)$/ + platform_version $1 + when /^KernelID =\s+(.+)$/ + platform_build $1 + end + end +end + +File.open("/etc/release") do |file| + while line = file.gets + case line + when /^.*(SmartOS).*$/ + platform "smartos" + when /^\s*(OmniOS).*r(\d+).*$/ + platform "omnios" + platform_version $2 + when /^\s*(OpenIndiana).*oi_(\d+).*$/ + platform "openindiana" + platform_version $2 + when /^\s*(OpenSolaris).*snv_(\d+).*$/ + platform "opensolaris" + platform_version $2 + when /^\s*(Oracle Solaris) (\d+)\s.*$/ + platform "solaris2" + when /^\s*(Solaris)\s.*$/ + platform "solaris2" + when /^\s*(NexentaCore)\s.*$/ + platform "nexentacore" + end + end +end diff --git a/spec/data/plugins/v6/solaris2/ps.rb b/spec/data/plugins/v6/solaris2/ps.rb new file mode 100644 index 00000000..c1546a63 --- /dev/null +++ b/spec/data/plugins/v6/solaris2/ps.rb @@ -0,0 +1,23 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "command/ps" + +require_plugin 'command' + +command[:ps] = 'ps -ef'
\ No newline at end of file diff --git a/spec/data/plugins/v6/solaris2/uptime.rb b/spec/data/plugins/v6/solaris2/uptime.rb new file mode 100644 index 00000000..e39dfcf8 --- /dev/null +++ b/spec/data/plugins/v6/solaris2/uptime.rb @@ -0,0 +1,36 @@ +# +# Author:: Kurt Yoder (<ktyopscode@yoderhome.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +require 'date' +# It would be far better if we could include sys/uptime from sys-uptime RubyGem +# It would also be good if we could pull idle time; how do we do this on Solaris? + +provides "uptime", "uptime_seconds" + +# Example output: +# $ who -b +# . system boot Jul 9 17:51 +popen4('who -b') do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + if line =~ /.* boot (.+)/ + uptime_seconds Time.now.to_i - DateTime.parse($1).strftime('%s').to_i + uptime self._seconds_to_human(uptime_seconds) + break + end + end +end diff --git a/spec/data/plugins/v6/solaris2/virtualization.rb b/spec/data/plugins/v6/solaris2/virtualization.rb new file mode 100644 index 00000000..fee8358d --- /dev/null +++ b/spec/data/plugins/v6/solaris2/virtualization.rb @@ -0,0 +1,91 @@ +# +# Author:: Sean Walbran (<seanwalbran@gmail.com>) +# Author:: Kurt Yoder (<ktyopscode@yoderhome.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# Copyright:: Copyright (c) 2010 Kurt Yoder +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "virtualization" + +virtualization Mash.new + +# Detect KVM/QEMU from cpuinfo, report as KVM +psrinfo_path="/usr/sbin/psrinfo" +if File.exists?(psrinfo_path) + popen4(psrinfo_path + " -pv") do |pid, stdin, stdout, stderr| + stdin.close + psr_info = stdout.read + if psr_info =~ /QEMU Virtual CPU/ + virtualization[:system] = "kvm" + virtualization[:role] = "guest" + end + end +end + +# http://www.dmo.ca/blog/detecting-virtualization-on-linux +smbios_path="/usr/sbin/smbios" +if File.exists?(smbios_path) + popen4(smbios_path) do |pid, stdin, stdout, stderr| + stdin.close + dmi_info = stdout.read + case dmi_info + when /Manufacturer: Microsoft/ + if dmi_info =~ /Product: Virtual Machine/ + virtualization[:system] = "virtualpc" + virtualization[:role] = "guest" + end + when /Manufacturer: VMware/ + if dmi_info =~ /Product: VMware Virtual Platform/ + virtualization[:system] = "vmware" + virtualization[:role] = "guest" + end + else + nil + end + end +end + +if File.executable?('/usr/sbin/zoneadm') + zones = Mash.new + + popen4("zoneadm list -pc") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each{ |line| + info = line.chomp.split(/:/) + zones[info[1]] = { + 'id' => info[0], + 'state' => info[2], + 'root' => info[3], + 'uuid' => info[4], + 'brand' => info[5], + 'ip' => info[6], + } + } + + if (zones.length == 1) + first_zone = zones.keys[0] + unless( first_zone == 'global') + virtualization[:system] = 'zone' + virtualization[:role] = 'guest' + virtualization[:guest_uuid] = zones[first_zone]['uuid'] + end + elsif (zones.length > 1) + virtualization[:system] = 'zone' + virtualization[:role] = 'host' + virtualization[:guests] = zones + end + end +end diff --git a/spec/data/plugins/v6/solaris2/zpools.rb b/spec/data/plugins/v6/solaris2/zpools.rb new file mode 100644 index 00000000..3e2420d8 --- /dev/null +++ b/spec/data/plugins/v6/solaris2/zpools.rb @@ -0,0 +1,64 @@ +# +# Author:: Jason J. W. Williams (williamsjj@digitar.com) +# Copyright:: Copyright (c) 2011 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "zpools" + +pools = Mash.new + +# Grab ZFS zpools overall health and attributes +popen4("zpool list -H -o name,size,alloc,free,cap,dedup,health,version") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^([-_0-9A-Za-z]*)\s+([.0-9]+[MGTPE])\s+([.0-9]+[MGTPE])\s+([.0-9]+[MGTPE])\s+(\d+%)\s+([.0-9]+x)\s+([-_0-9A-Za-z]+)\s+(\d+)$/ + pools[$1] = Mash.new + pools[$1][:pool_size] = $2 + pools[$1][:pool_allocated] = $3 + pools[$1][:pool_free] = $4 + pools[$1][:capacity_used] = $5 + pools[$1][:dedup_factor] = $6 + pools[$1][:health] = $7 + pools[$1][:zpool_version] = $8 + end + end +end + +# Grab individual health for devices in the zpools +for pool in pools.keys + pools[pool][:devices] = Mash.new + # Run "zpool status" as non-root user (adm) so that + # the command won't try to open() each device which can + # hang the command if any of the disks are bad. + popen4("su adm -c \"zpool status #{pool}\"") do |pid, stdin, stdout, stderr| + stdin.close + stdout.each do |line| + case line + when /^\s+(c[-_a-zA-Z0-9]+)\s+([-_a-zA-Z0-9]+)\s+(\d+)\s+(\d+)\s+(\d+)$/ + pools[pool][:devices][$1] = Mash.new + pools[pool][:devices][$1][:state] = $2 + pools[pool][:devices][$1][:errors] = Mash.new + pools[pool][:devices][$1][:errors][:read] = $3 + pools[pool][:devices][$1][:errors][:write] = $4 + pools[pool][:devices][$1][:errors][:checksum] = $5 + end + end + end +end + +# Set the zpools data +zpools pools
\ No newline at end of file diff --git a/spec/data/plugins/v6/ssh_host_key.rb b/spec/data/plugins/v6/ssh_host_key.rb new file mode 100644 index 00000000..6fb7f57a --- /dev/null +++ b/spec/data/plugins/v6/ssh_host_key.rb @@ -0,0 +1,73 @@ +# +# Author:: Bryan McLellan <btm@opscode.com> +# Copyright:: Copyright (c) 2012 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "keys/ssh" +require_plugin "keys" + +keys[:ssh] = Mash.new + +def extract_keytype?(content) + case content[0] + when "ssh-dss" + [ "dsa", nil ] + when "ssh-rsa" + [ "rsa", nil ] + when /^ecdsa/ + [ "ecdsa", content[0] ] + else + [ nil, nil ] + end +end + +sshd_config = if File.exists?("/etc/ssh/sshd_config") + "/etc/ssh/sshd_config" + elsif File.exists?("/etc/sshd_config") + # Darwin + "/etc/sshd_config" + else + Ohai::Log.debug("Failed to find sshd configuration file") + nil + end + +if sshd_config + File.open(sshd_config) do |conf| + conf.each_line do |line| + if line.match(/^hostkey\s/i) + pub_file = "#{line.split[1]}.pub" + content = IO.read(pub_file).split + key_type, key_subtype = extract_keytype?(content) + keys[:ssh]["host_#{key_type}_public"] = content[1] unless key_type.nil? + keys[:ssh]["host_#{key_type}_type"] = key_subtype unless key_subtype.nil? + end + end + end +end + +if keys[:ssh][:host_dsa_public].nil? && File.exists?("/etc/ssh/ssh_host_dsa_key.pub") + keys[:ssh][:host_dsa_public] = IO.read("/etc/ssh/ssh_host_dsa_key.pub").split[1] +end + +if keys[:ssh][:host_rsa_public].nil? && File.exists?("/etc/ssh/ssh_host_rsa_key.pub") + keys[:ssh][:host_rsa_public] = IO.read("/etc/ssh/ssh_host_rsa_key.pub").split[1] +end + +if keys[:ssh][:host_ecdsa_public].nil? && File.exists?("/etc/ssh/ssh_host_ecdsa_key.pub") + content = IO.read("/etc/ssh/ssh_host_ecdsa_key.pub") + keys[:ssh][:host_ecdsa_public] = content.split[1] + keys[:ssh][:host_ecdsa_type] = content.split[0] +end diff --git a/spec/data/plugins/v6/uptime.rb b/spec/data/plugins/v6/uptime.rb new file mode 100644 index 00000000..1930a746 --- /dev/null +++ b/spec/data/plugins/v6/uptime.rb @@ -0,0 +1,42 @@ +# +# Author:: Adam Jacob (<adam@opscode.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +def _seconds_to_human(seconds) + days = seconds.to_i / 86400 + seconds -= 86400 * days + + hours = seconds.to_i / 3600 + seconds -= 3600 * hours + + minutes = seconds.to_i / 60 + seconds -= 60 * minutes + + if days > 1 + return sprintf("%d days %02d hours %02d minutes %02d seconds", days, hours, minutes, seconds) + elsif days == 1 + return sprintf("%d day %02d hours %02d minutes %02d seconds", days, hours, minutes, seconds) + elsif hours > 0 + return sprintf("%d hours %02d minutes %02d seconds", hours, minutes, seconds) + elsif minutes > 0 + return sprintf("%d minutes %02d seconds", minutes, seconds) + else + return sprintf("%02d seconds", seconds) + end +end + + diff --git a/spec/data/plugins/v6/virtualization.rb b/spec/data/plugins/v6/virtualization.rb new file mode 100644 index 00000000..a1b62737 --- /dev/null +++ b/spec/data/plugins/v6/virtualization.rb @@ -0,0 +1,86 @@ +# +# Author:: Benjamin Black (<bb@opscode.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "virtualization" + +require_plugin "#{os}::virtualization" + +unless virtualization.nil? || !(virtualization[:role].eql?("host")) + begin + require 'libvirt' + require 'hpricot' + + emu = (virtualization[:system].eql?('kvm') ? 'qemu' : virtualization[:system]) + virtualization[:libvirt_version] = Libvirt::version(emu)[0].to_s + + virtconn = Libvirt::open_read_only("#{emu}:///system") + + virtualization[:uri] = virtconn.uri + virtualization[:capabilities] = Mash.new + virtualization[:capabilities][:xml_desc] = (virtconn.capabilities.split("\n").collect {|line| line.strip}).join + #xdoc = Hpricot virtualization[:capabilities][:xml_desc] + + virtualization[:nodeinfo] = Mash.new + ni = virtconn.node_get_info + ['cores','cpus','memory','mhz','model','nodes','sockets','threads'].each {|a| virtualization[:nodeinfo][a] = ni.send(a)} + + virtualization[:domains] = Mash.new + virtconn.list_domains.each do |d| + dv = virtconn.lookup_domain_by_id d + virtualization[:domains][dv.name] = Mash.new + virtualization[:domains][dv.name][:id] = d + virtualization[:domains][dv.name][:xml_desc] = (dv.xml_desc.split("\n").collect {|line| line.strip}).join + ['os_type','uuid'].each {|a| virtualization[:domains][dv.name][a] = dv.send(a)} + ['cpu_time','max_mem','memory','nr_virt_cpu','state'].each {|a| virtualization[:domains][dv.name][a] = dv.info.send(a)} + #xdoc = Hpricot virtualization[:domains][dv.name][:xml_desc] + + end + + virtualization[:networks] = Mash.new + virtconn.list_networks.each do |n| + nv = virtconn.lookup_network_by_name n + virtualization[:networks][n] = Mash.new + virtualization[:networks][n][:xml_desc] = (nv.xml_desc.split("\n").collect {|line| line.strip}).join + ['bridge_name','uuid'].each {|a| virtualization[:networks][n][a] = nv.send(a)} + #xdoc = Hpricot virtualization[:networks][n][:xml_desc] + + end + + virtualization[:storage] = Mash.new + virtconn.list_storage_pools.each do |pool| + sp = virtconn.lookup_storage_pool_by_name pool + virtualization[:storage][pool] = Mash.new + virtualization[:storage][pool][:xml_desc] = (sp.xml_desc.split("\n").collect {|line| line.strip}).join + ['autostart','uuid'].each {|a| virtualization[:storage][pool][a] = sp.send(a)} + ['allocation','available','capacity','state'].each {|a| virtualization[:storage][pool][a] = sp.info.send(a)} + #xdoc = Hpricot virtualization[:storage][pool][:xml_desc] + + virtualization[:storage][pool][:volumes] = Mash.new + sp.list_volumes.each do |v| + virtualization[:storage][pool][:volumes][v] = Mash.new + sv = sp.lookup_volume_by_name v + ['key','name','path'].each {|a| virtualization[:storage][pool][:volumes][v][a] = sv.send(a)} + ['allocation','capacity','type'].each {|a| virtualization[:storage][pool][:volumes][v][a] = sv.info.send(a)} + end + end + + virtconn.close + rescue LoadError => e + Ohai::Log.debug("Can't load gem: #{e}. virtualization plugin is disabled.") + end +end diff --git a/spec/data/plugins/v6/windows/cpu.rb b/spec/data/plugins/v6/windows/cpu.rb new file mode 100644 index 00000000..4fb1f4fe --- /dev/null +++ b/spec/data/plugins/v6/windows/cpu.rb @@ -0,0 +1,64 @@ +# +# Author:: Doug MacEachern <dougm@vmware.com> +# Copyright:: Copyright (c) 2010 VMware, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'ruby-wmi' + +provides "cpu" + +cpuinfo = Mash.new +cpu_number = 0 +index = 0 + +WMI::Win32_Processor.find(:all).each do |processor| + # + # On Windows Server 2003 R2 (i.e. 5.2.*), numberofcores property + # doesn't exist on the Win32_Processor class unless the user has + # patched their system with: + # http://support.microsoft.com/kb/932370 + # + # We're returning nil for cpu["cores"] and cpu["count"] + # when we don't see numberofcores property + # + + number_of_cores = nil + begin + number_of_cores = processor.numberofcores + cpu_number += number_of_cores + rescue NoMethodError => e + Ohai::Log.info("Can not find numberofcores property on Win32_Processor. Consider applying this patch: http://support.microsoft.com/kb/932370") + end + + current_cpu = index.to_s + index += 1 + cpuinfo[current_cpu] = Mash.new + cpuinfo[current_cpu]["vendor_id"] = processor.manufacturer + cpuinfo[current_cpu]["family"] = processor.family.to_s + cpuinfo[current_cpu]["model"] = processor.revision.to_s + cpuinfo[current_cpu]["stepping"] = processor.stepping + cpuinfo[current_cpu]["physical_id"] = processor.deviceid + #cpuinfo[current_cpu]["core_id"] = XXX + cpuinfo[current_cpu]["cores"] = number_of_cores + cpuinfo[current_cpu]["model_name"] = processor.description + cpuinfo[current_cpu]["mhz"] = processor.maxclockspeed.to_s + cpuinfo[current_cpu]["cache_size"] = "#{processor.l2cachesize} KB" + #cpuinfo[current_cpu]["flags"] = XXX +end + +cpu cpuinfo +cpu[:total] = (cpu_number == 0) ? nil : cpu_number +cpu[:real] = index diff --git a/spec/data/plugins/v6/windows/filesystem.rb b/spec/data/plugins/v6/windows/filesystem.rb new file mode 100644 index 00000000..efec6f0c --- /dev/null +++ b/spec/data/plugins/v6/windows/filesystem.rb @@ -0,0 +1,44 @@ +# +# Author:: James Gartrell (<jgartrel@gmail.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'ruby-wmi' + +fs = Mash.new +ld_info = Mash.new + +# Grab filesystem data from WMI +# Note: we should really be parsing Win32_Volume and Win32_Mapped drive +disks = WMI::Win32_LogicalDisk.find(:all) +disks.each do |disk| + filesystem = disk.DeviceID + fs[filesystem] = Mash.new + ld_info[filesystem] = Mash.new + disk.properties_.each do |p| + ld_info[filesystem][p.name.wmi_underscore.to_sym] = disk.send(p.name) + end + fs[filesystem][:kb_size] = ld_info[filesystem][:size].to_i / 1000 + fs[filesystem][:kb_available] = ld_info[filesystem][:free_space].to_i / 1000 + fs[filesystem][:kb_used] = fs[filesystem][:kb_size].to_i - fs[filesystem][:kb_available].to_i + fs[filesystem][:percent_used] = (fs[filesystem][:kb_size].to_i != 0 ? fs[filesystem][:kb_used].to_i * 100 / fs[filesystem][:kb_size].to_i : 0) + fs[filesystem][:mount] = ld_info[filesystem][:name] + fs[filesystem][:fs_type] = ld_info[filesystem][:file_system].downcase unless ld_info[filesystem][:file_system] == nil + fs[filesystem][:volume_name] = ld_info[filesystem][:volume_name] +end + +# Set the filesystem data +filesystem fs diff --git a/spec/data/plugins/v6/windows/hostname.rb b/spec/data/plugins/v6/windows/hostname.rb new file mode 100644 index 00000000..66a8cdf6 --- /dev/null +++ b/spec/data/plugins/v6/windows/hostname.rb @@ -0,0 +1,33 @@ +# +# Author:: James Gartrell (<jgartrel@gmail.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'ruby-wmi' +require 'socket' + +host = WMI::Win32_ComputerSystem.find(:first) +hostname "#{host.Name}" + +info = Socket.gethostbyname(Socket.gethostname) +if info.first =~ /.+?\.(.*)/ + fqdn info.first +else + #host is not in dns. optionally use: + #C:\WINDOWS\system32\drivers\etc\hosts + fqdn Socket.gethostbyaddr(info.last).first +end + diff --git a/spec/data/plugins/v6/windows/kernel.rb b/spec/data/plugins/v6/windows/kernel.rb new file mode 100644 index 00000000..ad45f4b2 --- /dev/null +++ b/spec/data/plugins/v6/windows/kernel.rb @@ -0,0 +1,58 @@ +# +# Author:: James Gartrell (<jgartrel@gmail.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'ruby-wmi' + +WIN32OLE.codepage = WIN32OLE::CP_UTF8 + +def machine_lookup(sys_type) + return "i386" if sys_type.eql?("X86-based PC") + return "x86_64" if sys_type.eql?("x64-based PC") + sys_type +end + +def os_lookup(sys_type) + return "Unknown" if sys_type.to_s.eql?("0") + return "Other" if sys_type.to_s.eql?("1") + return "MSDOS" if sys_type.to_s.eql?("14") + return "WIN3x" if sys_type.to_s.eql?("15") + return "WIN95" if sys_type.to_s.eql?("16") + return "WIN98" if sys_type.to_s.eql?("17") + return "WINNT" if sys_type.to_s.eql?("18") + return "WINCE" if sys_type.to_s.eql?("19") + return nil +end + +host = WMI::Win32_OperatingSystem.find(:first) +kernel[:os_info] = Mash.new +host.properties_.each do |p| + kernel[:os_info][p.name.wmi_underscore.to_sym] = host.send(p.name) +end + +kernel[:name] = "#{kernel[:os_info][:caption]}" +kernel[:release] = "#{kernel[:os_info][:version]}" +kernel[:version] = "#{kernel[:os_info][:version]} #{kernel[:os_info][:csd_version]} Build #{kernel[:os_info][:build_number]}" +kernel[:os] = os_lookup(kernel[:os_info][:os_type]) || languages[:ruby][:host_os] + +host = WMI::Win32_ComputerSystem.find(:first) +kernel[:cs_info] = Mash.new +host.properties_.each do |p| + kernel[:cs_info][p.name.wmi_underscore.to_sym] = host.send(p.name) +end + +kernel[:machine] = machine_lookup("#{kernel[:cs_info][:system_type]}") diff --git a/spec/data/plugins/v6/windows/kernel_devices.rb b/spec/data/plugins/v6/windows/kernel_devices.rb new file mode 100644 index 00000000..69da6c39 --- /dev/null +++ b/spec/data/plugins/v6/windows/kernel_devices.rb @@ -0,0 +1,39 @@ +# +# Author:: James Gartrell (<jgartrel@gmail.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +require 'ruby-wmi' + +WIN32OLE.codepage = WIN32OLE::CP_UTF8 + +kext = Mash.new +pnp_drivers = Mash.new + +drivers = WMI::Win32_PnPSignedDriver.find(:all) +drivers.each do |driver| + pnp_drivers[driver.DeviceID] = Mash.new + driver.properties_.each do |p| + pnp_drivers[driver.DeviceID][p.name.wmi_underscore.to_sym] = driver.send(p.name) + end + if driver.DeviceName + kext[driver.DeviceName] = pnp_drivers[driver.DeviceID] + kext[driver.DeviceName][:version] = pnp_drivers[driver.DeviceID][:driver_version] + kext[driver.DeviceName][:date] = pnp_drivers[driver.DeviceID][:driver_date] ? pnp_drivers[driver.DeviceID][:driver_date].to_s[0..7] : nil + end +end + +kernel[:pnp_drivers] = pnp_drivers +kernel[:modules] = kext diff --git a/spec/data/plugins/v6/windows/network.rb b/spec/data/plugins/v6/windows/network.rb new file mode 100644 index 00000000..bf25c2f0 --- /dev/null +++ b/spec/data/plugins/v6/windows/network.rb @@ -0,0 +1,113 @@ +# +# Author:: James Gartrell (<jgartrel@gmail.com>) +# Copyright:: Copyright (c) 2008 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +provides "network" + +require 'ruby-wmi' + +def encaps_lookup(encap) + return "Ethernet" if encap.eql?("Ethernet 802.3") + encap +end + +iface = Mash.new +iface_config = Mash.new +iface_instance = Mash.new + +# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394217%28v=vs.85%29.aspx +adapters = WMI::Win32_NetworkAdapterConfiguration.find(:all) +adapters.each do |adapter| + i = adapter.Index + iface_config[i] = Mash.new + adapter.properties_.each do |p| + iface_config[i][p.name.wmi_underscore.to_sym] = adapter.invoke(p.name) + end +end + +# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394216(v=vs.85).aspx +adapters = WMI::Win32_NetworkAdapter.find(:all) +adapters.each do |adapter| + i = adapter.Index + iface_instance[i] = Mash.new + adapter.properties_.each do |p| + iface_instance[i][p.name.wmi_underscore.to_sym] = adapter.invoke(p.name) + end +end + +iface_instance.keys.each do |i| + if iface_config[i][:ip_enabled] and iface_instance[i][:net_connection_id] + cint = sprintf("0x%x", iface_instance[i][:interface_index] ? iface_instance[i][:interface_index] : iface_instance[i][:index] ).downcase + iface[cint] = Mash.new + iface[cint][:configuration] = iface_config[i] + iface[cint][:instance] = iface_instance[i] + + iface[cint][:counters] = Mash.new + iface[cint][:addresses] = Mash.new + iface[cint][:configuration][:ip_address].each_index do |i| + ip = iface[cint][:configuration][:ip_address][i] + _ip = IPAddress("#{ip}/#{iface[cint][:configuration][:ip_subnet][i]}") + iface[cint][:addresses][ip] = Mash.new( + :prefixlen => _ip.prefix + ) + if _ip.ipv6? + # inet6 address + iface[cint][:addresses][ip][:family] = "inet6" + iface[cint][:addresses][ip][:scope] = "Link" if ip =~ /^fe80/i + else + # should be an inet4 address + iface[cint][:addresses][ip][:netmask] = _ip.netmask.to_s + if iface[cint][:configuration][:ip_use_zero_broadcast] + iface[cint][:addresses][ip][:broadcast] = _ip.network.to_s + else + iface[cint][:addresses][ip][:broadcast] = _ip.broadcast.to_s + end + iface[cint][:addresses][ip][:family] = "inet" + end + end + # Apparently you can have more than one mac_address? Odd. + [iface[cint][:configuration][:mac_address]].flatten.each do |mac_addr| + iface[cint][:addresses][mac_addr] = { + "family" => "lladdr" + } + end + iface[cint][:mtu] = iface[cint][:configuration][:mtu] + iface[cint][:type] = iface[cint][:instance][:adapter_type] + iface[cint][:arp] = {} + iface[cint][:encapsulation] = encaps_lookup(iface[cint][:instance][:adapter_type]) + if iface[cint][:configuration][:default_ip_gateway] != nil and iface[cint][:configuration][:default_ip_gateway].size > 0 + network[:default_gateway] = iface[cint][:configuration][:default_ip_gateway].first + network[:default_interface] = cint + end + end +end + +cint=nil +status, stdout, stderr = run_command(:command => "arp -a") +if status == 0 + stdout.split("\n").each do |line| + if line =~ /^Interface:\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+[-]+\s+(0x\S+)/ + cint = $2.downcase + end + next unless iface[cint] + if line =~ /^\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([a-fA-F0-9\:-]+)/ + iface[cint][:arp][$1] = $2.gsub("-",":").downcase + end + end +end + +network["interfaces"] = iface diff --git a/spec/data/plugins/v6/windows/platform.rb b/spec/data/plugins/v6/windows/platform.rb new file mode 100644 index 00000000..c0947c25 --- /dev/null +++ b/spec/data/plugins/v6/windows/platform.rb @@ -0,0 +1,27 @@ +# +# Author:: James Gartrell (<jgartrel@gmail.com>) +# Copyright:: Copyright (c) 2009 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# After long discussion in IRC the "powers that be" have come to a concensus +# that there is no other Windows platforms exist that were not based on the +# Windows_NT kernel, so we herby decree that "windows" will refer to all +# platforms built upon the Windows_NT kernel and have access to win32 or win64 +# subsystems. +platform os +platform_version kernel['release'] +platform_family "windows" + diff --git a/spec/data/plugins/v6/windows/uptime.rb b/spec/data/plugins/v6/windows/uptime.rb new file mode 100644 index 00000000..7ad4ab75 --- /dev/null +++ b/spec/data/plugins/v6/windows/uptime.rb @@ -0,0 +1,23 @@ +# +# Author:: Paul Mooring (paul@opscode.com) +# Copyright:: Copyright (c) 2012 Opscode, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +require 'ruby-wmi' + +provides "uptime", "uptime_seconds" + +uptime_seconds ::WMI::Win32_PerfFormattedData_PerfOS_System.find(:first).SystemUpTime.to_i +uptime self._seconds_to_human(uptime_seconds) diff --git a/spec/unit/loader_spec.rb b/spec/unit/loader_spec.rb index 2f7c2a06..8206bfdf 100644 --- a/spec/unit/loader_spec.rb +++ b/spec/unit/loader_spec.rb @@ -20,6 +20,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb') describe Ohai::Loader do before(:all) do + @v6plugin_path = File.expand_path("../../data/plugins/v6", __FILE__) @plugin_path = File.expand_path("../../data/plugins/loader", __FILE__) end @@ -84,4 +85,36 @@ describe Ohai::Loader do @ohai.attributes["easy"]["providers"].should eql(["easy"]) end end + + it "should add plugin_path to sources" do + path = File.expand_path("easy.rb", @plugin_path) + @loader.load_plugin(path) + @ohai.sources.has_key?(path).should be_true + end + + context "when loading v6 plugins" do + it "should save the plugin for future loading" do + Ohai::Config[:plugin_path] = [@v6plugin_path] + path = File.expand_path("os.rb", @v6plugin_path) + @loader.load_plugin(path) + @ohai.v6plugins.has_key?("os").should be_true + @ohai.sources.has_key?(path).should be_true + end + + it "should not load the plugin as a class" do + path = File.expand_path("os.rb", @v6plugin_path) + Ohai::Config[:plugin_path] = [path] + @loader.load_plugin(path) + @ohai.attributes.has_key?("os").should be_false + @ohai.plugins.has_key?("os").should be_false + end + end + + it "should load both v6 and v7 plugins" do + path = File.expand_path(File.dirname(__FILE__) + '/../data/plugins/mix') + Ohai::Config[:plugin_path] = [path] + @ohai.load_plugins + @ohai.sources.keys.sort.should eql(Dir[File.join(path, '*')].sort) + end + end diff --git a/spec/unit/system_spec.rb b/spec/unit/system_spec.rb index ea2f3e90..c4b2827a 100644 --- a/spec/unit/system_spec.rb +++ b/spec/unit/system_spec.rb @@ -40,6 +40,7 @@ describe Ohai::System, "load_plugins" do it "should load plugins when plugin_path has a trailing slash" do Ohai::Config[:plugin_path] = ["/tmp/plugins/"] + File.stub(:open).and_return(false) File.stub(:expand_path).with("/tmp/plugins/").and_return("/tmp/plugins") # windows Dir.should_receive(:[]).with("/tmp/plugins/*").and_return(["/tmp/plugins/darius.rb"]) Dir.should_receive(:[]).with("/tmp/plugins/#{Ohai::OS.collect_os}/**/*").and_return([]) |