class SysInfo

SysInfo

A container for the platform specific system information. Portions of this code were originally from Amazon's EC2 AMI tools, specifically lib/platform.rb.

Constants

ARCHITECTURES
IMPLEMENTATIONS
VERSION

Public Class Methods

new() click to toggle source
# File lib/sysinfo.rb, line 78
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

Public Instance Methods

find_hostname() click to toggle source

Return the hostname for the local machine

# File lib/sysinfo.rb, line 115
def find_hostname; Socket.gethostname; end
find_ipaddress_internal() click to toggle source

Return the local IP address which receives external traffic from: coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/ NOTE: This does not open a connection to the IP address.

# File lib/sysinfo.rb, line 136
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
find_network_info() click to toggle source

Returns [hostname, ipaddr (internal), uptime]

# File lib/sysinfo.rb, line 103
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
find_platform_info() click to toggle source

Returns [vm, os, impl, arch]

# File lib/sysinfo.rb, line 87
def find_platform_info
  vm, os, impl, arch = :ruby, :unknown, :unknown, :unknow
  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
find_uptime() click to toggle source

Returns the local uptime in hours. Use Win32API in Windows, 'sysctl -b kern.boottime' os osx, and 'who -b' on unix. Based on Ruby Quiz solutions by: Matthias Reitinger On Windows, see also: net statistics server

# File lib/sysinfo.rb, line 121
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
home() click to toggle source

Returns the path to the current user's home directory

# File lib/sysinfo.rb, line 153
def home; execute_platform_specific(:home); end
paths() click to toggle source

Returns the environment paths as an Array

# File lib/sysinfo.rb, line 151
def paths; execute_platform_specific(:paths); end
platform() click to toggle source

Returns a String of the full platform descriptor in the format: VM-OS-IMPL-ARCH e.g. java-unix-osx-x86_64

# File lib/sysinfo.rb, line 146
def platform
  "#{@vm}-#{@os}-#{@impl}-#{@arch}"
end
shell() click to toggle source

Returns the name of the current shell

# File lib/sysinfo.rb, line 155
def shell; execute_platform_specific(:shell); end
tmpdir() click to toggle source

Returns the path to the current temp directory

# File lib/sysinfo.rb, line 157
def tmpdir; execute_platform_specific(:tmpdir); end

Private Instance Methods

execute_platform_specific(dtype) click to toggle source

Look for and execute a platform specific method. The name of the method will be in the format: dtype-VM-OS-IMPL. e.g. #find_uptime_ruby_unix_osx

# File lib/sysinfo.rb, line 165
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
find_uptime_java_unix_osx()
find_uptime_java_windows_windows() click to toggle source

Ya, this is kinda wack. Ruby -> Java -> Kernel32. See: www.oreillynet.com/ruby/blog/2008/01/jruby_meets_the_windows_api_1.html

msdn.microsoft.com/en-us/library/ms724408(VS.85).aspx Ruby 1.9.1: Win32API is now deprecated in favor of using the DL library.

# File lib/sysinfo.rb, line 208
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
find_uptime_ruby_unix() click to toggle source

This should work for most unix flavours.

# File lib/sysinfo.rb, line 224
def find_uptime_ruby_unix
  # who is sloooooow. Use File.read('/proc/uptime')
  (Time.now.to_i - Time.parse(%x`who -b 2>/dev/null`).to_f)
end
Also aliased as: find_uptime_java_unix_osx
find_uptime_ruby_unix_osx() click to toggle source
# File lib/sysinfo.rb, line 218
def find_uptime_ruby_unix_osx
  # This is faster than "who" and could work on BSD also. 
  (Time.now.to_f - Time.at(%x`sysctl -b kern.boottime 2>/dev/null`.unpack('L').first).to_f).to_f
end
find_uptime_ruby_windows_windows() click to toggle source
# File lib/sysinfo.rb, line 213
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
getpwattr(pwattr) click to toggle source

Returns a named attribute of the user's /etc/password entry, or nil. As an example, `getpwdattr(:home)` will return the user's home directory without relying on ENV being present.

# File lib/sysinfo.rb, line 273
def getpwattr(pwattr)
  passwd = Etc.getpwuid(Process::Sys.getuid) || {}
  passwd[pwattr]
end
guess_java() click to toggle source

Determine the values for vm, os, impl, and arch when running on Java.

# File lib/sysinfo.rb, line 231
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
home_java() click to toggle source
# File lib/sysinfo.rb, line 196
def home_java
  if @impl == :windows
    File.expand_path(ENV['USERPROFILE'])
  else
    File.expand_path(getpwattr(:dir))
  end
end
home_ruby_unix() click to toggle source
# File lib/sysinfo.rb, line 194
def home_ruby_unix; File.expand_path(getpwattr(:dir)); end
home_ruby_windows() click to toggle source
# File lib/sysinfo.rb, line 195
def home_ruby_windows; File.expand_path(ENV['USERPROFILE']); end
ip_address_internal_alt() click to toggle source

Returns the local IP address based on the hostname. According to coderrr (see comments on blog link above), this implementation doesn't guarantee that it will return the address for the interface external traffic goes through. It's also possible the hostname isn't resolvable to the local IP.

NOTE: This code predates the current ip_address_internal. It was just as well but the other code is cleaner. I'm keeping this old version here for now.

# File lib/sysinfo.rb, line 260
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
paths_java() click to toggle source
# File lib/sysinfo.rb, line 177
def paths_java
  delim = @impl == :windows ? ';' : ':'
  (ENV['PATH'] || '').split(delim)
end
paths_ruby_unix() click to toggle source
# File lib/sysinfo.rb, line 175
def paths_ruby_unix; (ENV['PATH'] || '').split(':'); end
paths_ruby_windows() click to toggle source
# File lib/sysinfo.rb, line 176
def paths_ruby_windows; (ENV['PATH'] || '').split(';'); end
shell_java_unix()
Alias for: shell_ruby_unix
shell_java_windows()
Alias for: shell_ruby_windows
shell_ruby_unix() click to toggle source
# File lib/sysinfo.rb, line 189
def shell_ruby_unix; (ENV['SHELL'] || getpwattr(:shell) || 'bash').to_sym; end
Also aliased as: shell_java_unix
shell_ruby_windows() click to toggle source
# File lib/sysinfo.rb, line 190
def shell_ruby_windows; :dos; end
Also aliased as: shell_java_windows
tmpdir_java() click to toggle source
# File lib/sysinfo.rb, line 184
def tmpdir_java
  default = @impl == :windows ? 'C:\temp' : '/tmp'
  (Dir.tmpdir || default)
end
tmpdir_ruby_unix() click to toggle source
# File lib/sysinfo.rb, line 182
def tmpdir_ruby_unix; (Dir.tmpdir || '/tmp'); end
tmpdir_ruby_windows() click to toggle source
# File lib/sysinfo.rb, line 183
def tmpdir_ruby_windows; (Dir.tmpdir || 'C:\temp'); end