class SysInfo
specifically lib/platform.rb.
Portions of this code were originally from Amazon’s EC2 AMI tools,
A container for the platform specific system information.
= SysInfo
def execute_platform_specific(dtype)
e.g. find_uptime_ruby_unix_osx
The name of the method will be in the format: +dtype-VM-OS-IMPL+.
Look for and execute a platform specific method.
def execute_platform_specific(dtype) criteria = [@vm, @os, @impl] while !criteria.empty? meth = [dtype, criteria].join('_').to_sym return self.send(meth) if SysInfo.private_method_defined?(meth) criteria.pop end raise "#{dtype}_#{@vm}_#{@os}_#{@impl} not implemented" end
def find_hostname; Socket.gethostname; end
def find_hostname; Socket.gethostname; end
def find_ipaddress_internal
from: http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/
Return the local IP address which receives external traffic
def find_ipaddress_internal # turn off reverse DNS resolution temporarily orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true UDPSocket.open {|s| s.connect('65.74.177.129', 1); s.addr.last } # GitHub IP ensure Socket.do_not_reverse_lookup = orig end
def find_network_info
def find_network_info hostname, ipaddr, uptime = :unknown, :unknown, :unknown begin hostname = find_hostname ipaddr = find_ipaddress_internal uptime = find_uptime rescue => ex # Be silent! end [hostname, ipaddr, uptime] end
def find_platform_info
def find_platform_info vm, os, impl, arch = :ruby, :unknown, :unknown, :unknown IMPLEMENTATIONS.each do |r, o, i| next unless RUBY_PLATFORM =~ r os, impl = [o, i] break end ARCHITECTURES.each do |r, a| next unless RUBY_PLATFORM =~ r arch = a break end os == :java ? guess_java : [vm, os, impl, arch] end
def find_uptime
Based on Ruby Quiz solutions by: Matthias Reitinger
'sysctl -b kern.boottime' os osx, and 'who -b' on unix.
Returns the local uptime in hours. Use Win32API in Windows,
def find_uptime hours = 0 begin seconds = execute_platform_specific("find_uptime") || 0 hours = seconds / 3600 # seconds to hours rescue => ex #puts ex.message # TODO: implement debug? end hours end
def find_uptime_java_windows_windows
http://msdn.microsoft.com/en-us/library/ms724408(VS.85).aspx
http://www.oreillynet.com/ruby/blog/2008/01/jruby_meets_the_windows_api_1.html
Ya, this is kinda wack. Ruby -> Java -> Kernel32. See:
def find_uptime_java_windows_windows kernel32 = com.sun.jna.NativeLibrary.getInstance('kernel32') buf = java.nio.ByteBuffer.allocate(256) (kernel32.getFunction('GetTickCount').invokeInt([256, buf].to_java).to_f / 1000).to_f end
def find_uptime_ruby_unix
def find_uptime_ruby_unix # who is sloooooow. Use File.read('/proc/uptime') (Time.now.to_i - Time.parse(`who -b 2>/dev/null`).to_f) end
def find_uptime_ruby_unix_osx
def find_uptime_ruby_unix_osx # This is faster than "who" and could work on BSD also. (Time.now.to_f - Time.at(`sysctl -b kern.boottime 2>/dev/null`.unpack('L').first).to_f).to_f end
def find_uptime_ruby_windows_windows
def find_uptime_ruby_windows_windows # Win32API is required in self.guess getTickCount = Win32API.new("kernel32", "GetTickCount", nil, 'L') ((getTickCount.call()).to_f / 1000).to_f end
def getpwattr(pwattr)
As an example, `getpwdattr(:home)` will return the user's home directory
Returns a named attribute of the user's /etc/password entry, or nil.
def getpwattr(pwattr) passwd = Etc.getpwuid(Process::Sys.getuid) || {} passwd[pwattr] end
def guess_java
def guess_java vm, os, impl, arch = :java, :unknown, :unknown, :unknown require 'java' include_class java.lang.System unless defined?(System) osname = System.getProperty("os.name") IMPLEMENTATIONS.each do |r, o, i| next unless osname =~ r os, impl = [o, i] break end osarch = System.getProperty("os.arch") ARCHITECTURES.each do |r, a| next unless osarch =~ r arch = a break end [vm, os, impl, arch] end
def home; execute_platform_specific(:home); end
def home; execute_platform_specific(:home); end
def home_java
def home_java if @impl == :windows File.expand_path(ENV['USERPROFILE']) else File.expand_path(getpwattr(:dir)) end end
def home_ruby_unix; File.expand_path(getpwattr(:dir)); end
def home_ruby_unix; File.expand_path(getpwattr(:dir)); end
def home_ruby_windows; File.expand_path(ENV['USERPROFILE']); end
def home_ruby_windows; File.expand_path(ENV['USERPROFILE']); end
def initialize
def initialize @vm, @os, @impl, @arch = find_platform_info @hostname, @ipaddress_internal, @uptime = find_network_info @ruby = RUBY_VERSION.split('.').collect { |v| v.to_i } @user = getpwattr(:name) || ENV['USER'] require 'Win32API' if @os == :windows && @vm == :ruby end
def ip_address_internal_alt
NOTE: This code predates the current ip_address_internal. It was just as well
local IP.
traffic goes through. It's also possible the hostname isn't resolvable to the
doesn't guarantee that it will return the address for the interface external
According to coderrr (see comments on blog link above), this implementation
Returns the local IP address based on the hostname.
def ip_address_internal_alt ipaddr = :unknown begin saddr = Socket.getaddrinfo( Socket.gethostname, nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) ipaddr = saddr.select{|type| type[0] == 'AF_INET' }[0][3] rescue => ex end ipaddr end
def paths; execute_platform_specific(:paths); end
def paths; execute_platform_specific(:paths); end
def paths_java
def paths_java delim = @impl == :windows ? ';' : ':' (ENV['PATH'] || '').split(delim) end
def paths_ruby_unix; (ENV['PATH'] || '').split(':'); end
def paths_ruby_unix; (ENV['PATH'] || '').split(':'); end
def paths_ruby_windows; (ENV['PATH'] || '').split(';'); end # Not tested!
def paths_ruby_windows; (ENV['PATH'] || '').split(';'); end # Not tested!
def platform
Returns a String of the full platform descriptor in the format: VM-OS-IMPL-ARCH
def platform "#{@vm}-#{@os}-#{@impl}-#{@arch}" end
def shell; execute_platform_specific(:shell); end
def shell; execute_platform_specific(:shell); end
def shell_ruby_unix; (ENV['SHELL'] || getpwattr(:shell) || 'bash').to_sym; end
def shell_ruby_unix; (ENV['SHELL'] || getpwattr(:shell) || 'bash').to_sym; end
def shell_ruby_windows; :dos; end
def shell_ruby_windows; :dos; end
def tmpdir; execute_platform_specific(:tmpdir); end
def tmpdir; execute_platform_specific(:tmpdir); end
def tmpdir_java
def tmpdir_java default = @impl == :windows ? 'C:\\temp' : '/tmp' (Dir.tmpdir || default) end
def tmpdir_ruby_unix; (Dir.tmpdir || '/tmp'); end
def tmpdir_ruby_unix; (Dir.tmpdir || '/tmp'); end
def tmpdir_ruby_windows; (Dir.tmpdir || 'C:\\temp'); end
def tmpdir_ruby_windows; (Dir.tmpdir || 'C:\\temp'); end