summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-02-17 17:04:47 -0600
committerLuke Kanies <luke@madstop.com>2008-02-17 17:04:47 -0600
commit67da530118ce3cb3d318379ba4e79b3a1cb41511 (patch)
tree9073ed70eae952f94e1779288dac89045ae3d98f /lib
parent4bb9ed422c48464188e61cbdd58f9a721932129c (diff)
parentbd3b316dff14085ea633f95626b033147c146be7 (diff)
Merge branch 'os_split'
Conflicts: lib/facter/ipmess.rb
Diffstat (limited to 'lib')
-rw-r--r--lib/facter.rb516
-rw-r--r--lib/facter/cfengine.rb43
-rw-r--r--lib/facter/ipmess.rb49
-rw-r--r--lib/facter/kernel.rb46
-rw-r--r--lib/facter/lsb.rb38
-rw-r--r--lib/facter/macosx.rb38
-rw-r--r--lib/facter/manufacturer.rb53
-rw-r--r--lib/facter/memory.rb39
-rw-r--r--lib/facter/netmask.rb23
-rw-r--r--lib/facter/networking.rb312
-rw-r--r--lib/facter/os.rb115
-rw-r--r--lib/facter/process.rb29
-rw-r--r--lib/facter/processor.rb2
-rw-r--r--lib/facter/ssh.rb37
-rw-r--r--lib/facter/util/macosx.rb50
-rw-r--r--lib/facter/util/manufacturer.rb49
-rw-r--r--lib/facter/util/memory.rb54
17 files changed, 833 insertions, 660 deletions
diff --git a/lib/facter.rb b/lib/facter.rb
index b87805a..65ea57b 100644
--- a/lib/facter.rb
+++ b/lib/facter.rb
@@ -610,522 +610,6 @@ class Facter
end
end
- Facter.add(:kernel) do
- setcode 'uname -s'
- end
-
- Facter.add(:kernelrelease) do
- setcode 'uname -r'
- end
-
- { "LSBRelease" => %r{^LSB Version:\t(.*)$},
- "LSBDistId" => %r{^Distributor ID:\t(.*)$},
- "LSBDistRelease" => %r{^Release:\t(.*)$},
- "LSBDistDescription" => %r{^Description:\t(.*)$},
- "LSBDistCodeName" => %r{^Codename:\t(.*)$}
- }.each do |fact, pattern|
- Facter.add(fact) do
- setcode do
- unless defined?(@@lsbdata) and defined?(@@lsbtime) and (Time.now.to_i - @@lsbtime.to_i < 5)
- type = nil
- @@lsbtime = Time.now
- @@lsbdata = Resolution.exec('lsb_release -a 2>/dev/null')
- end
- if pattern.match(@@lsbdata)
- $1
- else
- nil
- end
- end
- end
- end
-
- Facter.add(:operatingsystem) do
- confine :kernel => :sunos
- setcode do "Solaris" end
- end
-
- Facter.add(:operatingsystem) do
- confine :kernel => :linux
- setcode do
- if Facter.lsbdistid == "Ubuntu"
- "Ubuntu"
- elsif FileTest.exists?("/etc/debian_version")
- "Debian"
- elsif FileTest.exists?("/etc/gentoo-release")
- "Gentoo"
- elsif FileTest.exists?("/etc/fedora-release")
- "Fedora"
- elsif FileTest.exists?("/etc/mandriva-release")
- "Mandriva"
- elsif FileTest.exists?("/etc/mandrake-release")
- "Mandrake"
- elsif FileTest.exists?("/etc/redhat-release")
- txt = File.read("/etc/redhat-release")
- if txt =~ /centos/i
- "CentOS"
- else
- "RedHat"
- end
- elsif FileTest.exists?("/etc/SuSE-release")
- "SuSE"
- end
- end
- end
-
- Facter.add(:operatingsystem) do
- # Default to just returning the kernel as the operating system
- setcode do Facter[:kernel].value end
- end
-
- Facter.add(:operatingsystemrelease) do
- confine :operatingsystem => :fedora
- setcode do
- File::open("/etc/fedora-release", "r") do |f|
- line = f.readline.chomp
- if line =~ /\(Rawhide\)$/
- "Rawhide"
- elsif line =~ /release (\d+)/
- $1
- end
- end
- end
- end
-
- Facter.add(:operatingsystemrelease) do
- confine :operatingsystem => %w{RedHat}
- setcode do
- File::open("/etc/redhat-release", "r") do |f|
- line = f.readline.chomp
- if line =~ /\(Rawhide\)$/
- "Rawhide"
- elsif line =~ /release (\d+)/
- $1
- end
- end
- end
- end
-
- Facter.add(:operatingsystemrelease) do
- confine :operatingsystem => %w{CentOS}
- setcode do
- release = Resolution.exec('rpm -q centos-release')
- if release =~ /release-(\d+)/
- $1
- end
- end
- end
-
- Facter.add(:operatingsystemrelease) do
- confine :operatingsystem => %w{Debian}
- setcode do
- release = Resolution.exec('cat /proc/version')
- if release =~ /\(Debian (\d+.\d+).\d+-\d+\)/
- $1
- end
- end
- end
-
- Facter.add(:operatingsystemrelease) do
- confine :operatingsystem => %w{Ubuntu}
- setcode do
- release = Resolution.exec('cat /etc/issue')
- if release =~ /Ubuntu (\d+.\d+)/
- $1
- end
- end
- end
-
- Facter.add(:operatingsystemrelease) do
- setcode do Facter[:kernelrelease].value end
- end
-
- Facter.add(:hardwaremodel) do
- setcode 'uname -m'
- end
-
- Facter.add(:architecture) do
- confine :kernel => :linux
- setcode do
- model = Facter.hardwaremodel
- case model
- # most linuxen use "x86_64"
- when 'x86_64':
- Facter.operatingsystem == "Debian" ? "amd64" : model;
- when /(i[3456]86|pentium)/: "i386"
- else
- model
- end
- end
- end
-
- Facter.add(:Cfkey) do
- setcode do
- value = nil
- ["/usr/local/etc/cfkey.pub",
- "/etc/cfkey.pub",
- "/var/cfng/keys/localhost.pub",
- "/var/cfengine/ppkeys/localhost.pub",
- "/var/lib/cfengine/ppkeys/localhost.pub",
- "/var/lib/cfengine2/ppkeys/localhost.pub"
- ].each { |file|
- if FileTest.file?(file)
- File.open(file) { |openfile|
- value = openfile.readlines.reject { |line|
- line =~ /PUBLIC KEY/
- }.collect { |line|
- line.chomp
- }.join("")
- }
- end
- if value
- break
- end
- }
-
- value
- end
- end
-
- Facter.add(:domain) do
- setcode do
- # First force the hostname to be checked
- Facter.hostname
-
- # Now check to see if it set the domain
- if defined? $domain and ! $domain.nil?
- $domain
- else
- nil
- end
- end
- end
- # Look for the DNS domain name command first.
- Facter.add(:domain) do
- setcode do
- domain = Resolution.exec('dnsdomainname') or nil
- # make sure it's a real domain
- if domain and domain =~ /.+\..+/
- domain
- else
- nil
- end
- end
- end
- Facter.add(:domain) do
- setcode do
- domain = Resolution.exec('domainname') or nil
- # make sure it's a real domain
- if domain and domain =~ /.+\..+/
- domain
- else
- nil
- end
- end
- end
- Facter.add(:domain) do
- setcode do
- value = nil
- if FileTest.exists?("/etc/resolv.conf")
- File.open("/etc/resolv.conf") { |file|
- # is the domain set?
- file.each { |line|
- if line =~ /domain\s+(\S+)/
- value = $1
- break
- end
- }
- }
- ! value and File.open("/etc/resolv.conf") { |file|
- # is the search path set?
- file.each { |line|
- if line =~ /search\s+(\S+)/
- value = $1
- break
- end
- }
- }
- value
- else
- nil
- end
- end
- end
- Facter.add(:hostname) do
- setldapname "cn"
- setcode do
- hostname = nil
- name = Resolution.exec('hostname') or nil
- if name
- if name =~ /^([\w-]+)\.(.+)$/
- hostname = $1
- # the Domain class uses this
- $domain = $2
- else
- hostname = name
- end
- hostname
- else
- nil
- end
- end
- end
-
- Facter.add(:fqdn) do
- setcode do
- host = Facter.value(:hostname)
- domain = Facter.value(:domain)
- if host and domain
- [host, domain].join(".")
- else
- nil
- end
- end
- end
-
- Facter.add(:ipaddress) do
- setldapname "iphostnumber"
- setcode do
- require 'resolv'
-
- begin
- if hostname = Facter.hostname
- ip = Resolv.getaddress(hostname)
- unless ip == "127.0.0.1"
- ip
- end
- else
- nil
- end
- rescue Resolv::ResolvError
- nil
- rescue NoMethodError # i think this is a bug in resolv.rb?
- nil
- end
- end
- end
- Facter.add(:ipaddress) do
- setcode do
- if hostname = Facter.hostname
- # we need Hostname to exist for this to work
- host = nil
- if host = Resolution.exec("host #{hostname}")
- host = host.chomp.split(/\s/)
- if defined? list[-1] and
- list[-1] =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/
- list[-1]
- end
- else
- nil
- end
- else
- nil
- end
- end
- end
-
- ["/etc/ssh","/usr/local/etc/ssh","/etc","/usr/local/etc"].each { |dir|
- {"SSHDSAKey" => "ssh_host_dsa_key.pub",
- "SSHRSAKey" => "ssh_host_rsa_key.pub"}.each { |name,file|
- Facter.add(name) do
- setcode do
- value = nil
- filepath = File.join(dir,file)
- if FileTest.file?(filepath)
- begin
- File.open(filepath) { |f|
- value = f.read.chomp.split(/\s+/)[1]
- }
- rescue
- value = nil
- end
- end
- value
- end # end of proc
- end # end of add
- } # end of hash each
- } # end of dir each
-
- Facter.add(:uniqueid) do
- setcode 'hostid', '/bin/sh'
- confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
- end
-
- Facter.add(:hardwareisa) do
- setcode 'uname -p', '/bin/sh'
- confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo FreeBSD OpenBSD NetBSD}
- end
-
- Facter.add(:macaddress) do
- confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
- setcode do
- ether = []
- output = %x{/sbin/ifconfig -a}
- output.each {|s|
- ether.push($1) if s =~ /(?:ether|HWaddr) (\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/
- }
- ether[0]
- end
- end
-
- Facter.add(:macaddress) do
- confine :operatingsystem => %w{FreeBSD OpenBSD}
- setcode do
- ether = []
- output = %x{/sbin/ifconfig}
- output.each {|s|
- if s =~ /(?:ether|lladdr)\s+(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
- ether.push($1)
- end
- }
- ether[0]
- end
- end
-
- Facter.add(:macaddress) do
- confine :kernel => :darwin
- setcode do
- ether = nil
- output = %x{/sbin/ifconfig}
-
- output.split(/^\S/).each { |str|
- if str =~ /10baseT/ # we're wired
- str =~ /ether (\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
- ether = $1
- end
- }
-
- ether
- end
- end
-
- Facter.add(:ipaddress) do
- confine :kernel => :linux
- setcode do
- ip = nil
- output = %x{/sbin/ifconfig}
-
- output.split(/^\S/).each { |str|
- if str =~ /inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
- tmp = $1
- unless tmp =~ /127\./
- ip = tmp
- break
- end
- end
- }
-
- ip
- end
- end
- Facter.add(:ipaddress) do
- confine :kernel => %w{FreeBSD OpenBSD solaris}
- setcode do
- ip = nil
- output = %x{/sbin/ifconfig}
-
- output.split(/^\S/).each { |str|
- if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
- tmp = $1
- unless tmp =~ /127\./
- ip = tmp
- break
- end
- end
- }
-
- ip
- end
- end
- Facter.add(:ipaddress) do
- confine :kernel => %w{NetBSD}
- setcode do
- ip = nil
- output = %x{/sbin/ifconfig -a}
-
- output.split(/^\S/).each { |str|
- if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
- tmp = $1
- unless tmp =~ /127\./
- ip = tmp
- break
- end
- end
- }
-
- ip
- end
- end
- Facter.add(:ipaddress) do
- confine :kernel => %w{darwin}
- setcode do
- ip = nil
- iface = ""
- output = %x{/usr/sbin/netstat -rn}
- if output =~ /^default\s*\S*\s*\S*\s*\S*\s*\S*\s*(\S*).*/
- iface = $1
- else
- warn "Could not find a default route. Using first non-loopback interface"
- end
- if(iface != "")
- output = %x{/sbin/ifconfig #{iface}}
- else
- output = %x{/sbin/ifconfig}
- end
-
- output.split(/^\S/).each { |str|
- if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
- tmp = $1
- unless tmp =~ /127\./
- ip = tmp
- break
- end
- end
- }
-
- ip
- end
- end
- Facter.add(:hostname) do
- confine :kernel => :darwin, :kernelrelease => "R7"
- setcode do
- %x{/usr/sbin/scutil --get LocalHostName}
- end
- end
- Facter.add(:iphostnumber) do
- confine :kernel => :darwin, :kernelrelease => "R6"
- setcode do
- %x{/usr/sbin/scutil --get LocalHostName}
- end
- end
- Facter.add(:iphostnumber) do
- confine :kernel => :darwin, :kernelrelease => "R6"
- setcode do
- ether = nil
- output = %x{/sbin/ifconfig}
-
- output =~ /HWaddr (\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
- ether = $1
-
- ether
- end
- end
-
- Facter.add(:ps) do
- setcode do 'ps -ef' end
- end
-
- Facter.add(:ps) do
- confine :operatingsystem => %w{FreeBSD NetBSD OpenBSD Darwin}
- setcode do 'ps -auxwww' end
- end
-
- Facter.add(:id) do
- #confine :kernel => %w{Solaris Linux}
- confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
- setcode "whoami"
- end
-
locals = []
# Now find all our loadable facts
diff --git a/lib/facter/cfengine.rb b/lib/facter/cfengine.rb
new file mode 100644
index 0000000..6db24db
--- /dev/null
+++ b/lib/facter/cfengine.rb
@@ -0,0 +1,43 @@
+## cfengine.rb
+## Facts related to cfengine
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+
+ Facter.add(:Cfkey) do
+ setcode do
+ value = nil
+ ["/usr/local/etc/cfkey.pub",
+ "/etc/cfkey.pub",
+ "/var/cfng/keys/localhost.pub",
+ "/var/cfengine/ppkeys/localhost.pub",
+ "/var/lib/cfengine/ppkeys/localhost.pub",
+ "/var/lib/cfengine2/ppkeys/localhost.pub"
+ ].each { |file|
+ if FileTest.file?(file)
+ File.open(file) { |openfile|
+ value = openfile.readlines.reject { |line|
+ line =~ /PUBLIC KEY/
+ }.collect { |line|
+ line.chomp
+ }.join("")
+ }
+ end
+ if value
+ break
+ end
+ }
+
+ value
+ end
+ end
+
diff --git a/lib/facter/ipmess.rb b/lib/facter/ipmess.rb
index b81048a..f8b4cf4 100644
--- a/lib/facter/ipmess.rb
+++ b/lib/facter/ipmess.rb
@@ -1,30 +1,21 @@
-#
-# ipmess.rb
-# Try to get additional Facts about the machine's network interfaces on Linux
-#
-# Original concept Copyright (C) 2007 psychedelys <psychedelys@gmail.com>
-# Update and *BSD support (C) 2007 James Turnbull <james@lovedthanlost.net>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation (version 2 of the License)
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
-#
+## ipmess.rb
+## Try to get additional Facts about the machine's network interfaces on Linux
+##
+## Original concept Copyright (C) 2007 psychedelys <psychedelys@gmail.com>
+## Update and *BSD support (C) 2007 James Turnbull <james@lovedthanlost.net>
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
-Facter.add(:interfaces) do
- confine :kernel => [ :freebsd, :openbsd, :netbsd, :linux ]
- setcode do
- output = %x{/sbin/ifconfig -a}
- int = nil
- int = output.scan(/(^\w+[.:]?\d+)/).join(" ")
- end
-end
+require 'facter/kernel'
Facter.add(:interfaces) do
confine :kernel => :sunos
@@ -35,7 +26,7 @@ Facter.add(:interfaces) do
end
end
-if Facter.kernel == "Linux"
+if Facter.value(:kernel) == "Linux"
interfaces = nil
interfaces = Facter.interfaces.split(" ")
@@ -70,7 +61,7 @@ if Facter.kernel == "Linux"
end
end
-if Facter.kernel == "FreeBSD" || Facter.kernel == "OpenBSD" || Facter.kernel == "NetBSD"
+if Facter.value(:kernel) == "FreeBSD" || Facter.value(:kernel) == "OpenBSD" || Facter.value(:kernel) == "NetBSD"
interfaces = nil
interfaces = Facter.interfaces.split(" ")
@@ -105,7 +96,7 @@ if Facter.kernel == "FreeBSD" || Facter.kernel == "OpenBSD" || Facter.kernel ==
end
end
-if Facter.kernel == "SunOS"
+if Facter.value(:kernel) == "SunOS"
interfaces = nil
interfaces = Facter.interfaces.split(" ")
diff --git a/lib/facter/kernel.rb b/lib/facter/kernel.rb
new file mode 100644
index 0000000..68f887a
--- /dev/null
+++ b/lib/facter/kernel.rb
@@ -0,0 +1,46 @@
+## kernel.rb
+## Facts related to the kernel, architecture and related
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+
+ Facter.add(:kernel) do
+ setcode 'uname -s'
+ end
+
+ Facter.add(:kernelrelease) do
+ setcode 'uname -r'
+ end
+
+ Facter.add(:hardwaremodel) do
+ setcode 'uname -m'
+ end
+
+ Facter.add(:architecture) do
+ confine :kernel => :linux
+ setcode do
+ model = Facter.value(:hardwaremodel)
+ case model
+ # most linuxen use "x86_64"
+ when 'x86_64':
+ Facter.value(:operatingsystem) == "Debian" ? "amd64" : model;
+ when /(i[3456]86|pentium)/: "i386"
+ else
+ model
+ end
+ end
+ end
+
+ Facter.add(:hardwareisa) do
+ setcode 'uname -p', '/bin/sh'
+ confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo FreeBSD OpenBSD NetBSD}
+ end
diff --git a/lib/facter/lsb.rb b/lib/facter/lsb.rb
new file mode 100644
index 0000000..c372213
--- /dev/null
+++ b/lib/facter/lsb.rb
@@ -0,0 +1,38 @@
+## lsb.rb
+## Facts related to Linux Standard Base (LSB)
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+
+{ "LSBRelease" => %r{^LSB Version:\t(.*)$},
+ "LSBDistId" => %r{^Distributor ID:\t(.*)$},
+ "LSBDistRelease" => %r{^Release:\t(.*)$},
+ "LSBDistDescription" => %r{^Description:\t(.*)$},
+ "LSBDistCodeName" => %r{^Codename:\t(.*)$}
+}.each do |fact, pattern|
+
+ Facter.add(fact) do
+ setcode do
+ unless defined?(@@lsbdata) and defined?(@@lsbtime) and (Time.now.to_i - @@lsbtime.to_i < 5)
+ type = nil
+ @@lsbtime = Time.now
+ @@lsbdata = Facter::Resolution.exec('lsb_release -a 2>/dev/null')
+ end
+
+ if pattern.match(@@lsbdata)
+ $1
+ else
+ nil
+ end
+ end
+ end
+end
diff --git a/lib/facter/macosx.rb b/lib/facter/macosx.rb
index 73339b7..60bd1ad 100644
--- a/lib/facter/macosx.rb
+++ b/lib/facter/macosx.rb
@@ -22,44 +22,14 @@
# at this point in time.
# In particular, Installed Software might be an interesting addition.
-module Facter::Macosx
- require 'thread'
- require 'facter/util/plist'
-
- # JJM I'd really like to dynamically generate these methods
- # by looking at the _name key of the _items dict for each _dataType
-
- def self.hardware_overview
- # JJM Perhaps we should cache the XML data in a "class" level object.
- top_level_plist = Plist::parse_xml %x{/usr/sbin/system_profiler -xml SPHardwareDataType}
- system_hardware = top_level_plist[0]['_items'][0]
- system_hardware.delete '_name'
- system_hardware
- end
-
- # SPSoftwareDataType
- def self.os_overview
- top_level_plist = Plist::parse_xml %x{/usr/sbin/system_profiler -xml SPSoftwareDataType}
- os_stuff = top_level_plist[0]['_items'][0]
- os_stuff.delete '_name'
- os_stuff
- end
-
- def self.sw_vers
- ver = Hash.new
- [ "productName", "productVersion", "buildVersion" ].each do |option|
- ver["macosx_#{option}"] = %x{sw_vers -#{option}}.strip
- end
- ver
- end
-end
+require 'facter/util/macosx'
-if Facter.kernel == "Darwin"
+if Facter.value(:kernel) == "Darwin"
Facter::Macosx.hardware_overview.each do |fact, value|
Facter.add("sp_#{fact}") do
confine :kernel => :darwin
setcode do
- value
+ value.to_s
end
end
end
@@ -68,7 +38,7 @@ if Facter.kernel == "Darwin"
Facter.add("sp_#{fact}") do
confine :kernel => :darwin
setcode do
- value
+ value.to_s
end
end
end
diff --git a/lib/facter/manufacturer.rb b/lib/facter/manufacturer.rb
index 9007539..67ca569 100644
--- a/lib/facter/manufacturer.rb
+++ b/lib/facter/manufacturer.rb
@@ -1,41 +1,20 @@
-# Info about the manufacturer
-#
-
-module Facter::Manufacturer
- def self.dmi_find_system_info(name)
- return nil unless FileTest.exists?("/usr/sbin/dmidecode")
-
- # Do not run the command more than every five seconds.
- unless defined?(@data) and defined?(@time) and (Time.now.to_i - @time.to_i < 5)
- @data = {}
- type = nil
- @time = Time.now
- # It's *much* easier to just parse the whole darn file than
- # to just match a chunk of it.
- %x{/usr/sbin/dmidecode 2>/dev/null}.split("\n").each do |line|
- case line
- when /^(\S.+)$/
- type = $1.chomp
- @data[type] ||= {}
- when /^\s+(\S.+): (\S.*)$/
- unless type
- next
- end
- @data[type][$1] = $2.strip
- end
- end
- end
-
- if data = @data["System Information"]
- data[name]
- else
- nil
- end
- end
-end
-
-# Add the facts to Facter
+## manufacturer.rb
+## Facts related to hardware manufacturer
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+require 'facter/util/manufacturer'
+
{:SerialNumber => "Serial Number",
:Manufacturer => "Manufacturer",
:ProductName=> "Product Name"}.each do |fact, name|
diff --git a/lib/facter/memory.rb b/lib/facter/memory.rb
index 6e9b600..c507089 100644
--- a/lib/facter/memory.rb
+++ b/lib/facter/memory.rb
@@ -16,44 +16,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
-module Facter::Memory
- require 'thread'
-
- def self.meminfo_number(tag)
- memsize = ""
- Thread::exclusive do
- size, scale = [0, ""]
- File.readlines("/proc/meminfo").each do |l|
- size, scale = [$1.to_f, $2] if l =~ /^#{tag}:\s+(\d+)\s+(\S+)/
- # MemoryFree == memfree + cached + buffers
- # (assume scales are all the same as memfree)
- if tag == "MemFree" &&
- l =~ /^(?:Buffers|Cached):\s+(\d+)\s+(?:\S+)/
- size += $1.to_f
- end
- end
- memsize = scale_number(size, scale)
- end
-
- memsize
- end
-
- def self.scale_number(size, multiplier)
- suffixes = ['', 'kB', 'MB', 'GB', 'TB']
-
- s = suffixes.shift
- while s != multiplier
- s = suffixes.shift
- end
-
- while size > 1024.0
- size /= 1024.0
- s = suffixes.shift
- end
-
- return "%.2f %s" % [size, s]
- end
-end
+require 'facter/util/memory'
{:MemorySize => "MemTotal",
:MemoryFree => "MemFree",
diff --git a/lib/facter/netmask.rb b/lib/facter/netmask.rb
index 1feb406..223d9e8 100644
--- a/lib/facter/netmask.rb
+++ b/lib/facter/netmask.rb
@@ -1,8 +1,21 @@
-# netmask.rb -- find the netmask of the primary ipaddress
-# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
-# Copyright (C) 2007 Mark 'phips' Phillips
-# See LICENSE for the full license granted to you.
-# idea and originial source by Mark 'phips' Phillips
+## netmask.rb
+## Find the netmask of the primary ipaddress
+## Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
+## Copyright (C) 2007 Mark 'phips' Phillips
+##
+## idea and originial source by Mark 'phips' Phillips
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
def get_netmask
netmask = nil;
diff --git a/lib/facter/networking.rb b/lib/facter/networking.rb
new file mode 100644
index 0000000..cde2c46
--- /dev/null
+++ b/lib/facter/networking.rb
@@ -0,0 +1,312 @@
+## networking.rb
+## Facts related to networking
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+
+ Facter.add(:domain) do
+ setcode do
+ # First force the hostname to be checked
+ Facter.hostname
+
+ # Now check to see if it set the domain
+ if defined? $domain and ! $domain.nil?
+ $domain
+ else
+ nil
+ end
+ end
+ end
+ # Look for the DNS domain name command first.
+ Facter.add(:domain) do
+ setcode do
+ domain = Facter::Resolution.exec('dnsdomainname') or nil
+ # make sure it's a real domain
+ if domain and domain =~ /.+\..+/
+ domain
+ else
+ nil
+ end
+ end
+ end
+ Facter.add(:domain) do
+ setcode do
+ domain = Facter::Resolution.exec('domainname') or nil
+ # make sure it's a real domain
+ if domain and domain =~ /.+\..+/
+ domain
+ else
+ nil
+ end
+ end
+ end
+ Facter.add(:domain) do
+ setcode do
+ value = nil
+ if FileTest.exists?("/etc/resolv.conf")
+ File.open("/etc/resolv.conf") { |file|
+ # is the domain set?
+ file.each { |line|
+ if line =~ /domain\s+(\S+)/
+ value = $1
+ break
+ end
+ }
+ }
+ ! value and File.open("/etc/resolv.conf") { |file|
+ # is the search path set?
+ file.each { |line|
+ if line =~ /search\s+(\S+)/
+ value = $1
+ break
+ end
+ }
+ }
+ value
+ else
+ nil
+ end
+ end
+ end
+ Facter.add(:hostname) do
+ setldapname "cn"
+ setcode do
+ hostname = nil
+ name = Facter::Resolution.exec('hostname') or nil
+ if name
+ if name =~ /^([\w-]+)\.(.+)$/
+ hostname = $1
+ # the Domain class uses this
+ $domain = $2
+ else
+ hostname = name
+ end
+ hostname
+ else
+ nil
+ end
+ end
+ end
+
+ Facter.add(:fqdn) do
+ setcode do
+ host = Facter.value(:hostname)
+ domain = Facter.value(:domain)
+ if host and domain
+ [host, domain].join(".")
+ else
+ nil
+ end
+ end
+ end
+
+ Facter.add(:ipaddress) do
+ setldapname "iphostnumber"
+ setcode do
+ require 'resolv'
+
+ begin
+ if hostname = Facter.value(:hostname)
+ ip = Resolv.getaddress(hostname)
+ unless ip == "127.0.0.1"
+ ip
+ end
+ else
+ nil
+ end
+ rescue Resolv::ResolvError
+ nil
+ rescue NoMethodError # i think this is a bug in resolv.rb?
+ nil
+ end
+ end
+ end
+ Facter.add(:ipaddress) do
+ setcode do
+ if hostname = Facter.value(:hostname)
+ # we need Hostname to exist for this to work
+ host = nil
+ if host = Facter::Resolution.exec("host #{hostname}")
+ host = host.chomp.split(/\s/)
+ if defined? list[-1] and
+ list[-1] =~ /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/
+ list[-1]
+ end
+ else
+ nil
+ end
+ else
+ nil
+ end
+ end
+ end
+
+ Facter.add(:uniqueid) do
+ setcode 'hostid', '/bin/sh'
+ confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
+ end
+
+ Facter.add(:macaddress) do
+ confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
+ setcode do
+ ether = []
+ output = %x{/sbin/ifconfig -a}
+ output.each {|s|
+ ether.push($1) if s =~ /(?:ether|HWaddr) (\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/
+ }
+ ether[0]
+ end
+ end
+
+ Facter.add(:macaddress) do
+ confine :operatingsystem => %w{FreeBSD OpenBSD}
+ setcode do
+ ether = []
+ output = %x{/sbin/ifconfig}
+ output.each {|s|
+ if s =~ /(?:ether|lladdr)\s+(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
+ ether.push($1)
+ end
+ }
+ ether[0]
+ end
+ end
+
+ Facter.add(:macaddress) do
+ confine :kernel => :darwin
+ setcode do
+ ether = nil
+ output = %x{/sbin/ifconfig}
+
+ output.split(/^\S/).each { |str|
+ if str =~ /10baseT/ # we're wired
+ str =~ /ether (\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
+ ether = $1
+ end
+ }
+
+ ether
+ end
+ end
+
+ Facter.add(:ipaddress) do
+ confine :kernel => :linux
+ setcode do
+ ip = nil
+ output = %x{/sbin/ifconfig}
+
+ output.split(/^\S/).each { |str|
+ if str =~ /inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
+ tmp = $1
+ unless tmp =~ /127\./
+ ip = tmp
+ break
+ end
+ end
+ }
+
+ ip
+ end
+ end
+ Facter.add(:ipaddress) do
+ confine :kernel => %w{FreeBSD OpenBSD solaris}
+ setcode do
+ ip = nil
+ output = %x{/sbin/ifconfig}
+
+ output.split(/^\S/).each { |str|
+ if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
+ tmp = $1
+ unless tmp =~ /127\./
+ ip = tmp
+ break
+ end
+ end
+ }
+
+ ip
+ end
+ end
+ Facter.add(:ipaddress) do
+ confine :kernel => %w{NetBSD}
+ setcode do
+ ip = nil
+ output = %x{/sbin/ifconfig -a}
+
+ output.split(/^\S/).each { |str|
+ if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
+ tmp = $1
+ unless tmp =~ /127\./
+ ip = tmp
+ break
+ end
+ end
+ }
+
+ ip
+ end
+ end
+ Facter.add(:ipaddress) do
+ confine :kernel => %w{darwin}
+ setcode do
+ ip = nil
+ iface = ""
+ output = %x{/usr/sbin/netstat -rn}
+ if output =~ /^default\s*\S*\s*\S*\s*\S*\s*\S*\s*(\S*).*/
+ iface = $1
+ else
+ warn "Could not find a default route. Using first non-loopback interface"
+ end
+ if(iface != "")
+ output = %x{/sbin/ifconfig #{iface}}
+ else
+ output = %x{/sbin/ifconfig}
+ end
+
+ output.split(/^\S/).each { |str|
+ if str =~ /inet ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
+ tmp = $1
+ unless tmp =~ /127\./
+ ip = tmp
+ break
+ end
+ end
+ }
+
+ ip
+ end
+ end
+ Facter.add(:hostname) do
+ confine :kernel => :darwin, :kernelrelease => "R7"
+ setcode do
+ %x{/usr/sbin/scutil --get LocalHostName}
+ end
+ end
+ Facter.add(:iphostnumber) do
+ confine :kernel => :darwin, :kernelrelease => "R6"
+ setcode do
+ %x{/usr/sbin/scutil --get LocalHostName}
+ end
+ end
+ Facter.add(:iphostnumber) do
+ confine :kernel => :darwin, :kernelrelease => "R6"
+ setcode do
+ ether = nil
+ output = %x{/sbin/ifconfig}
+
+ output =~ /HWaddr (\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)/
+ ether = $1
+
+ ether
+ end
+ end
+
diff --git a/lib/facter/os.rb b/lib/facter/os.rb
new file mode 100644
index 0000000..97d8093
--- /dev/null
+++ b/lib/facter/os.rb
@@ -0,0 +1,115 @@
+## os.rb
+## Facts related to operating systems and releases
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+
+ Facter.add(:operatingsystem) do
+ confine :kernel => :sunos
+ setcode do "Solaris" end
+ end
+
+ Facter.add(:operatingsystem) do
+ confine :kernel => :linux
+ setcode do
+ if Facter.value(:lsbdistid) == "Ubuntu"
+ "Ubuntu"
+ elsif FileTest.exists?("/etc/debian_version")
+ "Debian"
+ elsif FileTest.exists?("/etc/gentoo-release")
+ "Gentoo"
+ elsif FileTest.exists?("/etc/fedora-release")
+ "Fedora"
+ elsif FileTest.exists?("/etc/mandriva-release")
+ "Mandriva"
+ elsif FileTest.exists?("/etc/mandrake-release")
+ "Mandrake"
+ elsif FileTest.exists?("/etc/redhat-release")
+ txt = File.read("/etc/redhat-release")
+ if txt =~ /centos/i
+ "CentOS"
+ else
+ "RedHat"
+ end
+ elsif FileTest.exists?("/etc/SuSE-release")
+ "SuSE"
+ end
+ end
+ end
+
+ Facter.add(:operatingsystem) do
+ # Default to just returning the kernel as the operating system
+ setcode do Facter[:kernel].value end
+ end
+
+ Facter.add(:operatingsystemrelease) do
+ confine :operatingsystem => :fedora
+ setcode do
+ File::open("/etc/fedora-release", "r") do |f|
+ line = f.readline.chomp
+ if line =~ /\(Rawhide\)$/
+ "Rawhide"
+ elsif line =~ /release (\d+)/
+ $1
+ end
+ end
+ end
+ end
+
+ Facter.add(:operatingsystemrelease) do
+ confine :operatingsystem => %w{RedHat}
+ setcode do
+ File::open("/etc/redhat-release", "r") do |f|
+ line = f.readline.chomp
+ if line =~ /\(Rawhide\)$/
+ "Rawhide"
+ elsif line =~ /release (\d+)/
+ $1
+ end
+ end
+ end
+ end
+
+ Facter.add(:operatingsystemrelease) do
+ confine :operatingsystem => %w{CentOS}
+ setcode do
+ release = Facter::Resolution.exec('rpm -q centos-release')
+ if release =~ /release-(\d+)/
+ $1
+ end
+ end
+ end
+
+ Facter.add(:operatingsystemrelease) do
+ confine :operatingsystem => %w{Debian}
+ setcode do
+ release = Facter::Resolution.exec('cat /proc/version')
+ if release =~ /\(Debian (\d+.\d+).\d+-\d+\)/
+ $1
+ end
+ end
+ end
+
+ Facter.add(:operatingsystemrelease) do
+ confine :operatingsystem => %w{Ubuntu}
+ setcode do
+ release = Facter::Resolution.exec('cat /etc/issue')
+ if release =~ /Ubuntu (\d+.\d+)/
+ $1
+ end
+ end
+ end
+
+ Facter.add(:operatingsystemrelease) do
+ setcode do Facter[:kernelrelease].value end
+ end
+
diff --git a/lib/facter/process.rb b/lib/facter/process.rb
new file mode 100644
index 0000000..beeac47
--- /dev/null
+++ b/lib/facter/process.rb
@@ -0,0 +1,29 @@
+## process.rb
+## Facts related to ps and processes
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+ Facter.add(:ps) do
+ setcode do 'ps -ef' end
+ end
+
+ Facter.add(:ps) do
+ confine :operatingsystem => %w{FreeBSD NetBSD OpenBSD Darwin}
+ setcode do 'ps -auxwww' end
+ end
+
+ Facter.add(:id) do
+ #confine :kernel => %w{Solaris Linux}
+ confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE Debian Gentoo}
+ setcode "whoami"
+ end
+
diff --git a/lib/facter/processor.rb b/lib/facter/processor.rb
index 812bd99..069e06e 100644
--- a/lib/facter/processor.rb
+++ b/lib/facter/processor.rb
@@ -20,7 +20,7 @@
require 'thread'
-if Facter.kernel == "Linux"
+if Facter.value(:kernel) == "Linux"
processor_num = -1
processor_list = []
Thread::exclusive do
diff --git a/lib/facter/ssh.rb b/lib/facter/ssh.rb
new file mode 100644
index 0000000..29ea67c
--- /dev/null
+++ b/lib/facter/ssh.rb
@@ -0,0 +1,37 @@
+## ssh.rb
+## Facts related to SSH
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+
+ ["/etc/ssh","/usr/local/etc/ssh","/etc","/usr/local/etc"].each { |dir|
+ {"SSHDSAKey" => "ssh_host_dsa_key.pub",
+ "SSHRSAKey" => "ssh_host_rsa_key.pub"}.each { |name,file|
+ Facter.add(name) do
+ setcode do
+ value = nil
+ filepath = File.join(dir,file)
+ if FileTest.file?(filepath)
+ begin
+ File.open(filepath) { |f|
+ value = f.read.chomp.split(/\s+/)[1]
+ }
+ rescue
+ value = nil
+ end
+ end
+ value
+ end # end of proc
+ end # end of add
+ } # end of hash each
+ } # end of dir each
+
diff --git a/lib/facter/util/macosx.rb b/lib/facter/util/macosx.rb
new file mode 100644
index 0000000..1e596d8
--- /dev/null
+++ b/lib/facter/util/macosx.rb
@@ -0,0 +1,50 @@
+## macosx.rb
+## Support methods for Apple OSX facts
+##
+## Copyright (C) 2007 Jeff McCune
+## Author: Jeff McCune <jeff.mccune@northstarlabs.net>
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+
+module Facter::Macosx
+ require 'thread'
+ require 'facter/util/plist'
+
+ # JJM I'd really like to dynamically generate these methods
+ # by looking at the _name key of the _items dict for each _dataType
+
+ def self.hardware_overview
+ # JJM Perhaps we should cache the XML data in a "class" level object.
+ top_level_plist = Plist::parse_xml %x{/usr/sbin/system_profiler -xml SPHardwareDataType}
+ system_hardware = top_level_plist[0]['_items'][0]
+ system_hardware.delete '_name'
+ system_hardware
+ end
+
+ # SPSoftwareDataType
+ def self.os_overview
+ top_level_plist = Plist::parse_xml %x{/usr/sbin/system_profiler -xml SPSoftwareDataType}
+ os_stuff = top_level_plist[0]['_items'][0]
+ os_stuff.delete '_name'
+ os_stuff
+ end
+
+ def self.sw_vers
+ ver = Hash.new
+ [ "productName", "productVersion", "buildVersion" ].each do |option|
+ ver["macosx_#{option}"] = %x{sw_vers -#{option}}.strip
+ end
+ ver
+ end
+end
+
diff --git a/lib/facter/util/manufacturer.rb b/lib/facter/util/manufacturer.rb
new file mode 100644
index 0000000..18db1c9
--- /dev/null
+++ b/lib/facter/util/manufacturer.rb
@@ -0,0 +1,49 @@
+## mamufacturer.rb
+## Support methods for manufacturer specific facts
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+
+
+module Facter::Manufacturer
+ def self.dmi_find_system_info(name)
+ return nil unless FileTest.exists?("/usr/sbin/dmidecode")
+
+ # Do not run the command more than every five seconds.
+ unless defined?(@data) and defined?(@time) and (Time.now.to_i - @time.to_i < 5)
+ @data = {}
+ type = nil
+ @time = Time.now
+ # It's *much* easier to just parse the whole darn file than
+ # to just match a chunk of it.
+ %x{/usr/sbin/dmidecode 2>/dev/null}.split("\n").each do |line|
+ case line
+ when /^(\S.+)$/
+ type = $1.chomp
+ @data[type] ||= {}
+ when /^\s+(\S.+): (\S.*)$/
+ unless type
+ next
+ end
+ @data[type][$1] = $2.strip
+ end
+ end
+ end
+
+ if data = @data["System Information"]
+ data[name]
+ else
+ nil
+ end
+ end
+end
+
diff --git a/lib/facter/util/memory.rb b/lib/facter/util/memory.rb
new file mode 100644
index 0000000..2004491
--- /dev/null
+++ b/lib/facter/util/memory.rb
@@ -0,0 +1,54 @@
+## memory.rb
+## Support module for memory related facts
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation (version 2 of the License)
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston MA 02110-1301 USA
+##
+
+module Facter::Memory
+ require 'thread'
+
+ def self.meminfo_number(tag)
+ memsize = ""
+ Thread::exclusive do
+ size, scale = [0, ""]
+ File.readlines("/proc/meminfo").each do |l|
+ size, scale = [$1.to_f, $2] if l =~ /^#{tag}:\s+(\d+)\s+(\S+)/
+ # MemoryFree == memfree + cached + buffers
+ # (assume scales are all the same as memfree)
+ if tag == "MemFree" &&
+ l =~ /^(?:Buffers|Cached):\s+(\d+)\s+(?:\S+)/
+ size += $1.to_f
+ end
+ end
+ memsize = scale_number(size, scale)
+ end
+
+ memsize
+ end
+
+ def self.scale_number(size, multiplier)
+ suffixes = ['', 'kB', 'MB', 'GB', 'TB']
+
+ s = suffixes.shift
+ while s != multiplier
+ s = suffixes.shift
+ end
+
+ while size > 1024.0
+ size /= 1024.0
+ s = suffixes.shift
+ end
+
+ return "%.2f %s" % [size, s]
+ end
+end
+