class Object

Constants

MAC_MATCH
Mash

For historical reasons we inject Mash directly into the top level class namespace

Public Instance Methods

arch_lookup(sys_type) click to toggle source

given the SystemType value from WMI's Win32_ComputerSystem class msdn.microsoft.com/en-us/library/aa394102(v=vs.85).aspx return the architecture type @param [String] sys_type SystemType value from Win32_ComputerSystem @return [String] x86_64 or i386

# File lib/ohai/plugins/kernel.rb, line 86
def arch_lookup(sys_type)
  return "x86_64" if sys_type == "x64-based PC"
  return "i386" if sys_type == "X86-based PC"

  sys_type
end
arpname_to_ifname(iface, arpname) click to toggle source
# File lib/ohai/plugins/solaris2/network.rb, line 80
def arpname_to_ifname(iface, arpname)
  iface.each_key do |ifn|
    return ifn if ifn.split(":")[0].eql?(arpname)
  end

  nil
end
bigip_version() click to toggle source

Determines the platform version for F5 Big-IP systems

@deprecated

@returns [String] bigip Linux version from /etc/f5-release

# File lib/ohai/plugins/linux/platform.rb, line 91
def bigip_version
  release_contents = file_read("/etc/f5-release")
  release_contents.match(/BIG-IP release (\S*)/)[1] # http://rubular.com/r/O8nlrBVqSb
rescue NoMethodError, Errno::ENOENT, Errno::EACCES # rescue regex failure, file missing, or permission denied
  logger.warn("Detected F5 Big-IP, but /etc/f5-release could not be parsed to determine platform_version")
  nil
end
blocked_wmi_name?(name) click to toggle source

see if a WMI name is in the blocked list so we can avoid writing out useless data to ohai

@param [String] name the wmi name to check @return [Boolean] is the wmi name in the blocked list

# File lib/ohai/plugins/kernel.rb, line 144
def blocked_wmi_name?(name)
  [
   "creation_class_name", # this is just the wmi name
   "cs_creation_class_name", # this is just the wmi name
   "oem_logo_bitmap", # this is the entire OEM bitmap file
   "total_swap_space_size", # already in memory plugin
   "total_virtual_memory_size", # already in memory plugin
   "total_virtual_memory_size", # already in memory plugin
   "free_physical_memory", # already in memory plugin
   "free_space_in_paging_files", # already in memory plugin
   "free_virtual_memory", # already in memory plugin
  ].include?(name)
end
bsd_modules(path) click to toggle source

common *bsd code for collecting modules data @return [Mash]

# File lib/ohai/plugins/kernel.rb, line 44
def bsd_modules(path)
  modules = Mash.new
  so = shell_out(Ohai.abs_path(path).to_s)
  so.stdout.lines 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\_]+)/
      modules[$5] = { size: $4, refcount: $2 }
    end
  end
  modules
end
check_for_cl() click to toggle source
# File lib/ohai/plugins/c.rb, line 98
def check_for_cl
  # ms cl
  collect("cl /?") do |so|
    description = so.stderr.lines.first.chomp
    if description =~ /Compiler Version ([\d\.]+)/
      @c[:cl] = Mash.new
      @c[:cl][:version] = $1
      @c[:cl][:description] = description
    end
  end
end
check_for_devenv() click to toggle source
# File lib/ohai/plugins/c.rb, line 110
def check_for_devenv
  # ms vs
  collect("devenv.com /?") do |so|
    lines = so.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
end
check_routing_table(family, iface, default_route_table) click to toggle source

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 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)

# File lib/ohai/plugins/linux/network.rb, line 77
def check_routing_table(family, iface, default_route_table)
  so = shell_out("ip -o -f #{family[:name]} route show table #{default_route_table}")
  so.stdout.lines do |line|
    line.strip!
    logger.trace("Plugin Network: Parsing #{line}")
    if /\\/.match?(line)
      parts = line.split("\\")
      route_dest = parts.shift.strip
      route_endings = parts
    elsif line =~ /^([^\s]+)\s(.*)$/
      route_dest = $1
      route_endings = [$2]
    else
      next
    end
    route_endings.each do |route_ending|
      if route_ending =~ /\bdev\s+([^\s]+)\b/
        route_int = $1
      else
        logger.trace("Plugin Network: Skipping route entry without a device: '#{line}'")
        next
      end
      route_int = "venet0:0" if is_openvz? && !is_openvz_host? && route_int == "venet0" && iface["venet0:0"]

      unless iface[route_int]
        logger.trace("Plugin Network: 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|
        # http://rubular.com/r/pwTNp65VFf
        route_entry[k] = $1 if route_ending =~ /\b#{k}\s+([^\s]+)/
      end
      # https://rubular.com/r/k1sMrRn5yLjgVi
      route_entry["via"] = $1 if route_ending =~ /\bvia\s+inet6\s+([^\s]+)/

      # 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
      # unless the interface has no addresses of this type at all
      if route_entry[:src]
        addr = iface[route_int][:addresses]
        unless addr.nil? || addr.key?(route_entry[:src]) ||
            addr.values.all? { |a| a["family"] != family[:name] }
          logger.trace("Plugin Network: Skipping route entry whose src does not match the interface IP")
          next
        end
      end

      iface[route_int][:routes] = [] unless iface[route_int][:routes]
      iface[route_int][:routes] << route_entry
    end
  end
  iface
end
chef_effortless?() click to toggle source
# File lib/ohai/plugins/chef.rb, line 23
def chef_effortless?
  # Determine if client is being run as a Habitat package.
  if Chef::CHEF_ROOT.include?("hab/pkgs/chef/chef")
    # Determine if client is running in zero mode which would show it is using the Effortless pattern.
    # Explicitly set response to true or nil, not false
    ChefConfig::Config["chef_server_url"].include?("chefzero://")
  end
end
choose_default_route(routes) click to toggle source

returns the default route with the lowest metric (unspecified metric is 0)

# File lib/ohai/plugins/linux/network.rb, line 534
def choose_default_route(routes)
  routes.select do |r|
    r[:destination] == "default"
  end.min do |x, y|
    (x[:metric].nil? ? 0 : x[:metric].to_i) <=> (y[:metric].nil? ? 0 : y[:metric].to_i)
  end
end
collect(cmd) { |so| ... } click to toggle source
# File lib/ohai/plugins/c.rb, line 24
def collect(cmd, &block)
  so = shell_out(cmd)
  if so.exitstatus == 0
    yield(so)
  else
    logger.trace("Plugin C: '#{cmd}' failed. Skipping data.")
  end
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin C: '#{cmd}' binary could not be found. Skipping data.")
end
collect_domain() click to toggle source
# File lib/ohai/plugins/hostname.rb, line 53
def collect_domain
  # Domain is everything after the first dot
  if fqdn
    fqdn =~ /.+?\.(.*)/
    domain $1
  end
end
collect_gcc() click to toggle source
# File lib/ohai/plugins/c.rb, line 49
def collect_gcc
  # gcc
  # Sample output on os x:
  # Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
  # Apple LLVM version 7.3.0 (clang-703.0.29)
  # Target: x86_64-apple-darwin15.4.0
  # Thread model: posix
  # InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
  #
  #
  # Sample output on Linux:
  # Using built-in specs.
  # COLLECT_GCC=gcc
  # COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
  # Target: x86_64-linux-gnu
  # Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-trace --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
  # Thread model: posix
  # gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
  gcc = Mash.new
  collect("gcc -v") do |so|
    so.stderr.each_line do |line|
      case line
      when /^(.*version\s(\S*).*)/
        gcc[:description] = $1
        gcc[:version] = $2
      when /^Target:\s(.*)/
        gcc[:target] = $1
      when /^Configured with:\s(.*)/
        gcc[:configured_with] = $1
      when /^Thread model:\s(.*)/
        gcc[:thread_model] = $1
      end
    end
  end
  @c[:gcc] = gcc unless gcc.empty?
end
collect_glibc() click to toggle source
# File lib/ohai/plugins/c.rb, line 86
def collect_glibc
  # glibc
  collect("ldd --version") do |so|
    description = so.stdout.split($/).first
    if description =~ /(\d+\.\d+\.?\d*)/
      @c[:glibc] = Mash.new
      @c[:glibc][:version] = $1
      @c[:glibc][:description] = description
    end
  end
end
collect_hostname() click to toggle source
# File lib/ohai/plugins/hostname.rb, line 61
def collect_hostname
  # Hostname is everything before the first dot
  if machinename
    machinename =~ /([^.]+)\.?/
    hostname $1
  elsif fqdn
    fqdn =~ /(.+?)\./
    hostname $1
  end
end
collect_ips_packages() click to toggle source
# File lib/ohai/plugins/packages.rb, line 173
def collect_ips_packages
  so = shell_out("pkg list -H")
  # Output format is
  # NAME (PUBLISHER)    VERSION    IFO
  so.stdout.lines.each do |pkg|
    tokens = pkg.split
    if tokens.length == 3 # No publisher info
      name, version, = tokens
    else
      name, publisher, version, = tokens
      publisher = publisher[1..-2]
    end
    packages[name] = { "version" => version }
    packages[name]["publisher"] = publisher if publisher
  end
end
collect_old_version(shell_outs) click to toggle source
# File lib/ohai/plugins/filesystem.rb, line 664
def collect_old_version(shell_outs)
  mount_hash = parse_df_or_mount shell_outs[:mount]
  df_hash    = parse_df_or_mount shell_outs[:df_Pk]

  mount_hash.each do |key, hash|
    df_hash[key].merge!(hash) if df_hash.key?(key)
  end

  mount_hash.merge(df_hash)
end
collect_programs_from_registry_key(repo, key_path) click to toggle source
# File lib/ohai/plugins/packages.rb, line 109
def collect_programs_from_registry_key(repo, key_path)
  # from http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx
  if ::RbConfig::CONFIG["target_cpu"] == "i386"
    reg_type = Win32::Registry::KEY_READ | 0x100
  elsif ::RbConfig::CONFIG["target_cpu"] == "x86_64"
    reg_type = Win32::Registry::KEY_READ | 0x200
  else
    reg_type = Win32::Registry::KEY_READ
  end
  repo.open(key_path, reg_type) do |reg|
    reg.each_key do |key, _wtime|
      pkg = reg.open(key)
      name = pkg["DisplayName"] rescue nil
      next if name.nil?

      package = packages[name] = Mash.new
      WINDOWS_ATTRIBUTE_ALIASES.each do |registry_attr, package_attr|
        value = pkg[registry_attr] rescue nil
        package[package_attr] = value unless value.nil?
      end
    end
  end
end
collect_solaris_guestid() click to toggle source
# File lib/ohai/plugins/solaris2/virtualization.rb, line 28
def collect_solaris_guestid
  shell_out("/usr/sbin/zoneadm list -p").stdout.split(":").first
end
collect_sun_pro() click to toggle source
# File lib/ohai/plugins/c.rb, line 139
def collect_sun_pro
  # sun pro
  collect("cc -V -flags") do |so|
    output = so.stderr.split
    if so.stderr =~ /^cc: Sun C/ && output.size >= 4
      @c[:sunpro] = Mash.new
      @c[:sunpro][:version] = output[3]
      @c[:sunpro][:description] = so.stderr.chomp
    end
  end
end
collect_system_profiler_apps() click to toggle source
# File lib/ohai/plugins/packages.rb, line 215
def collect_system_profiler_apps
  require "plist"
  sp_std = shell_out("system_profiler SPApplicationsDataType -xml")
  results = Plist.parse_xml(sp_std.stdout)
  sw_array = results[0]["_items"]
  sw_array.each do |pkg|
    packages[pkg["_name"]] = {
      "version" => pkg["version"],
      "lastmodified" => pkg["lastModified"],
      "source" => pkg["obtained_from"],
    }
  end
end
collect_sysv_packages() click to toggle source
# File lib/ohai/plugins/packages.rb, line 190
def collect_sysv_packages
  so = shell_out("pkginfo -l")
  # Each package info is separated by a blank line
  chunked_lines = so.stdout.lines.map(&:strip).chunk do |line|
    !line.empty? || nil
  end
  chunked_lines.each do |_, lines| # rubocop: disable Style/HashEachMethods
    package = {}
    lines.each do |line|
      key, value = line.split(":", 2)
      package[key.strip.downcase] = value.strip unless value.nil?
    end
    # pkginst is the installed package name
    packages[package["pkginst"]] = package.tap do |p|
      p.delete("pkginst")
    end
  end
end
collect_uptime(path) click to toggle source
# File lib/ohai/plugins/uptime.rb, line 33
def collect_uptime(path)
  # kern.boottime: { sec = 1232765114, usec = 823118 } Fri Jan 23 18:45:14 2009
  so = shell_out("#{Ohai.abs_path(path)} kern.boottime")
  so.stdout.lines do |line|
    if line =~ /kern.boottime:\D+(\d+)/
      usec = Time.new.to_i - $1.to_i
      return [usec, seconds_to_human(usec)]
    end
  end
  [nil, nil]
end
collect_xlc() click to toggle source
# File lib/ohai/plugins/c.rb, line 123
def collect_xlc
  # IBM XL C/C++ for AIX, V13.1.3 (5725-C72, 5765-J07)
  # Version: 13.01.0003.0000
  so = shell_out("xlc -qversion")
  if so.exitstatus == 0 || (so.exitstatus >> 8) == 249
    description = so.stdout.split($/).first
    if description =~ /V(\d+\.\d+(.\d+)?)/
      @c[:xlc] = Mash.new
      @c[:xlc][:version] = $1
      @c[:xlc][:description] = description.strip
    end
  end
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin C: 'xlc' binary could not be found. Skipping data.")
end
create_raid_device_mash(stdout) click to toggle source
# File lib/ohai/plugins/linux/mdadm.rb, line 25
def create_raid_device_mash(stdout)
  device_mash = Mash.new
  device_mash[:device_counts] = Mash.new
  stdout.lines.each do |line|
    case line
    when /Version\s+: ([0-9.]+)/
      device_mash[:version] = Regexp.last_match[1].to_f
    when /Raid Level\s+: raid([0-9]+)/
      device_mash[:level] = Regexp.last_match[1].to_i
    when /Array Size.*\(([0-9.]+)/
      device_mash[:size] = Regexp.last_match[1].to_f
    when /State\s+: ([a-z]+)/
      device_mash[:state] = Regexp.last_match[1]
    when /Total Devices\s+: ([0-9]+)/
      device_mash[:device_counts][:total] = Regexp.last_match[1].to_i
    when /Raid Devices\s+: ([0-9]+)/
      device_mash[:device_counts][:raid] = Regexp.last_match[1].to_i
    when /Working Devices\s+: ([0-9]+)/
      device_mash[:device_counts][:working] = Regexp.last_match[1].to_i
    when /Failed Devices\s+: ([0-9]+)/
      device_mash[:device_counts][:failed] = Regexp.last_match[1].to_i
    when /Active Devices\s+: ([0-9]+)/
      device_mash[:device_counts][:active] = Regexp.last_match[1].to_i
    when /Spare Devices\s+: ([0-9]+)/
      device_mash[:device_counts][:spare] = Regexp.last_match[1].to_i
    end
  end
  device_mash
end
create_seed() { |src| ... } click to toggle source

Common sources go here. Put sources that need to be different per-platform under their collect_data block.

# File lib/ohai/plugins/shard.rb, line 65
def create_seed(&block)
  sources = Ohai.config[:plugin][:shard_seed][:sources] || default_sources
  data = ""
  sources.each do |src|
    data << case src
            when :fqdn
              fqdn
            when :hostname
              hostname
            when :machine_id
              machine_id
            when :machinename
              machinename
            else
              yield(src)
            end
  end
  if data.empty?
    Ohai::Log.error("shard_seed: Unable to generate seed! Either ensure 'dmidecode' is installed, or use 'Ohai.config[:plugin][:shard_seed][:sources]' to set different sources.")
    raise "Failed to generate shard_seed"
  end
  shard_seed digest_algorithm.hexdigest(data)[0...7].to_i(16)
end
darwin_encaps_lookup(ifname) click to toggle source
# File lib/ohai/plugins/darwin/network.rb, line 56
def darwin_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
default_digest_algorithm() click to toggle source
# File lib/ohai/plugins/shard.rb, line 42
def default_digest_algorithm
  if fips && fips["kernel"]["enabled"]
    # Even though it is being used safely, FIPS-mode will still blow up on
    # any use of MD5 so default to SHA2 instead.
    "sha256"
  else
    "md5"
  end
end
default_sources() click to toggle source
# File lib/ohai/plugins/shard.rb, line 33
def default_sources
  case collect_os
  when "linux", "darwin", "windows"
    %i{machinename serial uuid}
  else
    [:machinename]
  end
end
determine_os_version() click to toggle source

Grab the version from the VERSION_ID field and use the kernel release if that's not available. It should be there for everything, but rolling releases like arch / gentoo where we've traditionally used the kernel as the version @return String the OS version

# File lib/ohai/plugins/linux/platform.rb, line 286
def determine_os_version
  # centos only includes the major version in os-release for some reason
  if os_release_info["ID"] == "centos"
    get_redhatish_version(file_read("/etc/redhat-release").chomp)
  # debian testing and unstable don't have VERSION_ID set
  elsif os_release_info["ID"] == "debian"
    os_release_info["VERSION_ID"] || file_read("/etc/debian_version").chomp
  else
    os_release_info["VERSION_ID"] || shell_out("/bin/uname -r").stdout.strip
  end
end
digest_algorithm() click to toggle source
# File lib/ohai/plugins/shard.rb, line 52
def digest_algorithm
  case Ohai.config[:plugin][:shard_seed][:digest_algorithm] || default_digest_algorithm
  when "md5"
    require "digest/md5" unless defined?(Digest::MD5)
    Digest::MD5
  when "sha256"
    require "openssl/digest"
    OpenSSL::Digest::SHA256
  end
end
docker_exists?() click to toggle source
# File lib/ohai/plugins/darwin/virtualization.rb, line 42
def docker_exists?
  which("docker")
end
docker_info_json() click to toggle source
# File lib/ohai/plugins/docker.rb, line 23
def docker_info_json
  so = shell_out("docker info --format '{{json .}}'")
  if so.exitstatus == 0
    JSON.parse(so.stdout)
  end
rescue Ohai::Exceptions::Exec
  logger.trace('Plugin Docker: Could not shell_out "docker info --format \'{{json .}}\'". Skipping plugin')
end
docker_ohai_data(shellout_data) click to toggle source
# File lib/ohai/plugins/docker.rb, line 32
def docker_ohai_data(shellout_data)
  docker Mash.new
  docker[:version_string] = shellout_data["ServerVersion"]
  docker[:version] = shellout_data["ServerVersion"].split("-")[0] if shellout_data["ServerVersion"] # guard this so missing data doesn't fail the run
  docker[:runtimes] = shellout_data["Runtimes"]
  docker[:root_dir] = shellout_data["DockerRootDir"]
  docker[:containers] = {}
  docker[:containers][:total] = shellout_data["Containers"]
  docker[:containers][:running] = shellout_data["ContainersRunning"]
  docker[:containers][:paused] = shellout_data["ContainersPaused"]
  docker[:containers][:stopped] = shellout_data["ContainersStopped"]
  docker[:plugins] = shellout_data["Plugins"]
  docker[:networking] = {}
  docker[:networking][:ipv4_forwarding] = shellout_data["IPv4Forwarding"]
  docker[:networking][:bridge_nf_iptables] = shellout_data["BridgeNfIptables"]
  docker[:networking][:bridge_nf_ipv6_iptables] = shellout_data["BridgeNfIp6tables"]
  docker[:swarm] = shellout_data["Swarm"]
end
emu() click to toggle source
# File lib/ohai/plugins/libvirt.rb, line 29
def emu
  @emu ||= (virtualization[:system].eql?("kvm") ? "qemu" : virtualization[:system])
end
encryptable_info() click to toggle source

Returns a Mash loaded with encryption details

Uses Win32_EncryptableVolume and encryption_properties to return encryption details of volumes.

Returns an empty Mash in case of any WMI exception.

@note We are fetching Encryption Status only as of now

@see msdn.microsoft.com/en-us/library/windows/desktop/aa376483(v=vs.85).aspx

@return [Mash]

# File lib/ohai/plugins/filesystem.rb, line 177
def encryptable_info
  wmi = WmiLite::Wmi.new("Root\\CIMV2\\Security\\MicrosoftVolumeEncryption")
  disks = wmi.instances_of("Win32_EncryptableVolume")
  encryption_properties(disks)
rescue WmiLite::WmiException
  Ohai::Log.debug("Unable to access Win32_EncryptableVolume. Skipping encryptable details")
  Mash.new
end
encryption_properties(disks) click to toggle source

Refines and calculates encryption properties out of given instances

@param [WmiLite::Wmi::Instance] disks

@return [Mash] Each drive containing following properties:

* :encryption_status (String)
# File lib/ohai/plugins/filesystem.rb, line 237
def encryption_properties(disks)
  properties = Mash.new
  disks.each do |disk|
    property = Mash.new
    property[:encryption_status] = disk["conversionstatus"] ? CONVERSION_STATUS[disk["conversionstatus"]] : ""
    key = disk["driveletter"]
    properties[key] = property
  end
  properties
end
ethernet_channel_parameters(iface) click to toggle source

determine channel parameters for the interface using ethtool

# File lib/ohai/plugins/linux/network.rb, line 214
def ethernet_channel_parameters(iface)
  return iface unless ethtool_binary_path

  iface.each_key do |tmp_int|
    next unless iface[tmp_int][:encapsulation] == "Ethernet"

    so = shell_out("#{ethtool_binary_path} -l #{tmp_int}")
    logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
    type = nil
    iface[tmp_int]["channel_params"] = {}
    so.stdout.lines.each do |line|
      next if line.start_with?("Channel parameters for")
      next if line.strip.nil?

      if /Pre-set maximums/.match?(line)
        type = "max"
        next
      end
      if /Current hardware settings/.match?(line)
        type = "current"
        next
      end
      key, val = line.split(/:\s+/)
      if type && val
        channel_key = "#{type}_#{key.downcase.tr(" ", "_")}"
        iface[tmp_int]["channel_params"][channel_key] = val.to_i
      end
    end
  end
  iface
end
ethernet_coalesce_parameters(iface) click to toggle source

determine coalesce parameters for the interface using ethtool

# File lib/ohai/plugins/linux/network.rb, line 247
def ethernet_coalesce_parameters(iface)
  return iface unless ethtool_binary_path

  iface.each_key do |tmp_int|
    next unless iface[tmp_int][:encapsulation] == "Ethernet"

    so = shell_out("#{ethtool_binary_path} -c #{tmp_int}")
    logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
    iface[tmp_int]["coalesce_params"] = {}
    so.stdout.lines.each do |line|
      next if line.start_with?("Coalesce parameters for")
      next if line.strip.nil?

      if line.start_with?("Adaptive")
        _, adaptive_rx, _, adaptive_tx = line.split(/:\s+|\s+TX|\n/)
        iface[tmp_int]["coalesce_params"]["adaptive_rx"] = adaptive_rx
        iface[tmp_int]["coalesce_params"]["adaptive_tx"] = adaptive_tx
        next
      end
      key, val = line.split(/:\s+/)
      if val
        coalesce_key = key.downcase.tr(" ", "_").to_s
        iface[tmp_int]["coalesce_params"][coalesce_key] = val.to_i
      end
    end
  end
  iface
end
ethernet_driver_info(iface) click to toggle source

determine driver info for the interface using ethtool

# File lib/ohai/plugins/linux/network.rb, line 325
def ethernet_driver_info(iface)
  return iface unless ethtool_binary_path

  iface.each_key do |tmp_int|
    next unless iface[tmp_int][:encapsulation] == "Ethernet"

    so = shell_out("#{ethtool_binary_path} -i #{tmp_int}")
    logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
    iface[tmp_int]["driver_info"] = {}
    so.stdout.lines.each do |line|
      next if line.strip.nil?

      key, val = line.split(/:\s+/)
      if val.nil?
        val = ""
      end
      driver_key = key.downcase.tr(" ", "_").to_s
      iface[tmp_int]["driver_info"][driver_key] = val.chomp
    end
  end
  iface
end
ethernet_layer_one(iface) click to toggle source

determine layer 1 details for the interface using ethtool

# File lib/ohai/plugins/linux/network.rb, line 154
def ethernet_layer_one(iface)
  return iface unless ethtool_binary_path

  keys = %w{Speed Duplex Port Transceiver Auto-negotiation MDI-X}
  iface.each_key do |tmp_int|
    next unless iface[tmp_int][:encapsulation] == "Ethernet"

    so = shell_out("#{ethtool_binary_path} #{tmp_int}")
    so.stdout.lines do |line|
      line.chomp!
      logger.trace("Plugin Network: Parsing ethtool output: #{line}")
      line.lstrip!
      k, v = line.split(": ")
      next unless keys.include? k

      k.downcase!.tr!("-", "_")
      if k == "speed"
        k = "link_speed" # This is not necessarily the maximum speed the NIC supports
        v = v[/\d+/].to_i
      end
      iface[tmp_int][k] = v
    end
  end
  iface
end
ethernet_offload_parameters(iface) click to toggle source

determine offload features for the interface using ethtool

# File lib/ohai/plugins/linux/network.rb, line 277
def ethernet_offload_parameters(iface)
  return iface unless ethtool_binary_path

  iface.each_key do |tmp_int|
    next unless iface[tmp_int][:encapsulation] == "Ethernet"

    so = shell_out("#{ethtool_binary_path} -k #{tmp_int}")
    Ohai::Log.debug("Plugin Network: Parsing ethtool output: #{so.stdout}")
    iface[tmp_int]["offload_params"] = {}
    so.stdout.lines.each do |line|
      next if line.start_with?("Features for")
      next if line.strip.nil?

      key, val = line.split(/:\s+/)
      if val
        offload_key = key.downcase.strip.tr(" ", "_").to_s
        iface[tmp_int]["offload_params"][offload_key] = val.downcase.gsub(/\[.*\]/, "").strip.to_s
      end
    end
  end
  iface
end
ethernet_pause_parameters(iface) click to toggle source

determine pause parameters for the interface using ethtool

# File lib/ohai/plugins/linux/network.rb, line 301
def ethernet_pause_parameters(iface)
  return iface unless ethtool_binary_path

  iface.each_key do |tmp_int|
    next unless iface[tmp_int][:encapsulation] == "Ethernet"

    so = shell_out("#{ethtool_binary_path} -a #{tmp_int}")
    logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
    iface[tmp_int]["pause_params"] = {}
    so.stdout.lines.each do |line|
      next if line.start_with?("Pause parameters for")
      next if line.strip.nil?

      key, val = line.split(/:\s+/)
      if val
        pause_key = "#{key.downcase.tr(" ", "_")}"
        iface[tmp_int]["pause_params"][pause_key] = val.strip.eql? "on"
      end
    end
  end
  iface
end
ethernet_ring_parameters(iface) click to toggle source

determine ring parameters for the interface using ethtool

# File lib/ohai/plugins/linux/network.rb, line 181
def ethernet_ring_parameters(iface)
  return iface unless ethtool_binary_path

  iface.each_key do |tmp_int|
    next unless iface[tmp_int][:encapsulation] == "Ethernet"

    so = shell_out("#{ethtool_binary_path} -g #{tmp_int}")
    logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}")
    type = nil
    iface[tmp_int]["ring_params"] = {}
    so.stdout.lines.each do |line|
      next if line.start_with?("Ring parameters for")
      next if line.strip.nil?

      if /Pre-set maximums/.match?(line)
        type = "max"
        next
      end
      if /Current hardware settings/.match?(line)
        type = "current"
        next
      end
      key, val = line.split(/:\s+/)
      if type && val
        ring_key = "#{type}_#{key.downcase.tr(" ", "_")}"
        iface[tmp_int]["ring_params"][ring_key] = val.to_i
      end
    end
  end
  iface
end
ethtool_binary_path() click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 42
def ethtool_binary_path
  @ethtool ||= which("ethtool")
end
excluded_setting?(setting) click to toggle source
# File lib/ohai/plugins/darwin/network.rb, line 74
def excluded_setting?(setting)
  setting.match("_sw_cksum")
end
extract_keytype?(content) click to toggle source
# File lib/ohai/plugins/ssh_host_key.rb, line 24
def extract_keytype?(content)
  case content[0]
  when "ssh-dss"
    [ "dsa", nil ]
  when "ssh-rsa"
    [ "rsa", nil ]
  when /^ecdsa/
    [ "ecdsa", content[0] ]
  when "ssh-ed25519"
    [ "ed25519", nil ]
  else
    [ nil, nil ]
  end
end
extract_neighbors(family, iface, neigh_attr) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 54
def extract_neighbors(family, iface, neigh_attr)
  so = shell_out("ip -f #{family[:name]} neigh show")
  so.stdout.lines do |line|
    if line =~ /^([a-f0-9\:\.]+)\s+dev\s+([^\s]+)\s+lladdr\s+([a-fA-F0-9\:]+)/
      interface = iface[$2]
      unless interface
        logger.warn("neighbor list has entries for unknown interface #{interface}")
        next
      end
      interface[neigh_attr] ||= Mash.new
      interface[neigh_attr][$1] = $3.downcase
    end
  end
  iface
end
favored_default_route_linux(routes, iface, default_route, family) click to toggle source

ipv4/ipv6 routes are different enough that having a single algorithm to select the favored route for both creates unnecessary complexity this method attempts to deduce the route that is most important to the user, which is later used to deduce the favored values for {ip,mac,ip6}address we only consider routes that are default routes, or those routes that get us to the gateway for a default route

# File lib/ohai/plugins/linux/network.rb, line 583
def favored_default_route_linux(routes, iface, default_route, family)
  routes.select do |r|
    if family[:name] == "inet"
      # the route must have a source address
      next if r[:src].nil? || r[:src].empty?

      # the interface specified in the route must exist
      route_interface = iface[r[:dev]]
      next if route_interface.nil? # the interface specified in the route must exist

      # the interface must have no addresses, or if it has the source address, the address must not
      # be a link-level address
      next unless interface_valid_for_route?(route_interface, r[:src], "inet")

      # the route must either be a default route, or it must have a gateway which is accessible via the route
      next unless route_is_valid_default_route?(r, default_route)

      true
    elsif family[:name] == "inet6"
      iface[r[:dev]] &&
        iface[r[:dev]][:state] == "up" &&
        route_is_valid_default_route?(r, default_route)
    end
  end.min_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
end
favored_default_route_windows(configuration) click to toggle source

Selects default interface and returns its information

@note Interface with least metric value should be preferred as default_route

@param configuration [Mash] Configuration of interfaces as iface_config

[<interface_index> => {<interface_configurations>}]

@return [Hash<:index, :interface_index, :default_ip_gateway, :ip_connection_metric>]

# File lib/ohai/plugins/windows/network.rb, line 104
def favored_default_route_windows(configuration)
  return nil unless configuration.is_a?(Hash)

  config = configuration.dup

  config.inject([]) do |arr, (k, v)|
    if v["default_ip_gateway"]
      arr << { index: v["index"],
               interface_index: v["interface_index"],
               default_ip_gateway: prefer_ipv4(v["default_ip_gateway"]),
               ip_connection_metric: v["ip_connection_metric"] }
    end
    arr
  end.min_by { |r| r[:ip_connection_metric] }
end
fetch_habitat_packages() click to toggle source
# File lib/ohai/plugins/habitat.rb, line 32
def fetch_habitat_packages
  shell_out([habitat_binary, "pkg", "list", "--all"]).stdout.split.sort.select { |pkg| pkg.match?(%r{.*/.*/.*/.*}) }
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin Habitat: Unable to determine the installed Habitat packages, skipping collection.")
end
fetch_habitat_services() click to toggle source
# File lib/ohai/plugins/habitat.rb, line 56
def fetch_habitat_services
  services_shell_out = shell_out([habitat_binary, "svc", "status"]).stdout
  load_habitat_service_via_cli(services_shell_out) if services_shell_out
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin Habitat: Unable to determine the installed Habitat services, skipping collection.")
end
fetch_habitat_version() click to toggle source
# File lib/ohai/plugins/habitat.rb, line 26
def fetch_habitat_version
  shell_out([habitat_binary, "-V"]).stdout.gsub(/hab\s*/, "").strip
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin Habitat: Unable to determine the installed version of Habitat, skipping collection.")
end
fetch_ip_data(data, type, field) click to toggle source
# File lib/ohai/plugins/azure.rb, line 107
def fetch_ip_data(data, type, field)
  ips = []

  data[type]["ipAddress"].each do |val|
    ips << val[field] unless val[field].empty?
  end
  ips
end
file_val_if_exists(path) click to toggle source

return the contents of a file if the file exists @param path abs path to the file @return [String] contents of the file if it exists

# File lib/ohai/plugins/alibaba.rb, line 48
def file_val_if_exists(path)
  if file_exist?(path)
    file_read(path)
  end
end
find_device(name) click to toggle source
# File lib/ohai/plugins/filesystem.rb, line 29
def find_device(name)
  %w{/dev /dev/mapper}.each do |dir|
    path = File.join(dir, name)
    return path if file_exist?(path)
  end
  name
end
find_ip(family = "inet") click to toggle source

finds ip address / interface for interface with default route based on passed in family. returns [ipaddress, interface] uses 1st ip if no default route is found

# File lib/ohai/plugins/network.rb, line 65
def find_ip(family = "inet")
  ips = sorted_ips(family)

  # return if there aren't any #{family} addresses!
  return [ nil, nil ] if ips.empty?

  # shortcuts to access default #{family} interface and gateway
  int_attr = Ohai::Mixin::NetworkHelper::FAMILIES[family] + "_interface"
  gw_attr = Ohai::Mixin::NetworkHelper::FAMILIES[family] + "_gateway"

  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?
      logger.warn("Plugin Network: [#{family}] no ip address on #{network[int_attr]}")
    elsif network[gw_attr] &&
        network["interfaces"][network[int_attr]] &&
        network["interfaces"][network[int_attr]]["addresses"]
      if [ "0.0.0.0", "::", /^fe80:/ ].any? { |pat| pat === network[gw_attr] } # rubocop: disable Performance/RedundantEqualityComparisonBlock
        # link level default route
        logger.trace("Plugin Network: link level default #{family} route, picking ip from #{network[gw_attr]}")
        r = gw_if_ips.first
      else
        # checking network masks
        r = gw_if_ips.find do |v|
          network_contains_address(network[gw_attr], v[:ipaddress], v[:iface])
        end
        if r.nil?
          r = gw_if_ips.first
          logger.trace("Plugin Network: [#{family}] no ipaddress/mask on #{network[int_attr]} matching the gateway #{network[gw_attr]}, picking #{r[:ipaddress]}")
        else
          logger.trace("Plugin Network: [#{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
    logger.trace("Plugin Network: [#{family}] no default interface, picking the first ipaddress")
  end

  return [ nil, nil ] if r.nil? || r.empty?

  [ r[:ipaddress].to_s, r[:iface] ]
end
find_mac_from_iface(iface) click to toggle source

select mac address of first interface with family of lladdr

# File lib/ohai/plugins/network.rb, line 116
def find_mac_from_iface(iface)
  r = network["interfaces"][iface]["addresses"].select { |k, v| v["family"] == "lladdr" }
  r.nil? || r.first.nil? ? nil : r.first.first
end
fix_encoding(str) click to toggle source

@param [String] str

@return [String]

# File lib/ohai/plugins/passwd.rb, line 11
def fix_encoding(str)
  str.force_encoding(Encoding.default_external) if str.respond_to?(:force_encoding)
  str
end
from_cmd(cmd) click to toggle source

hostname : short hostname machinename : output of hostname command (might be short on solaris) fqdn : result of canonicalizing hostname using DNS or /etc/hosts domain : domain part of FQDN

hostname and machinename should always exist fqdn and domain may be broken if DNS is broken on the host

# File lib/ohai/plugins/hostname.rb, line 44
def from_cmd(cmd)
  shell_out(cmd).stdout.strip
end
full_interface_name(iface, part_name, index) click to toggle source
# File lib/ohai/plugins/solaris2/network.rb, line 88
def full_interface_name(iface, part_name, index)
  iface.each do |name, attrs|
    next unless attrs.respond_to?(:[])
    return name if /^#{part_name}($|:)/.match(name) && attrs[:index] == index
  end

  nil
end
fusion_exists?() click to toggle source
# File lib/ohai/plugins/darwin/virtualization.rb, line 38
def fusion_exists?
  file_exist?("/Applications/VMware\ Fusion.app/")
end
gather_pool_info() click to toggle source
# File lib/ohai/plugins/zpools.rb, line 30
def gather_pool_info
  pools = Mash.new
  begin
    # Grab ZFS zpools overall health and attributes
    so = shell_out("zpool list -H -o name,size,alloc,free,cap,dedup,health,version")
    so.stdout.lines 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+|-)$/
        Ohai::Log.debug("Plugin Zpools: Parsing zpool list line: #{line.chomp}")
        pools[$1] = Mash.new
        pools[$1][:pool_size] = sanitize_value($2)
        pools[$1][:pool_allocated] = sanitize_value($3)
        pools[$1][:pool_free] = sanitize_value($4)
        pools[$1][:capacity_used] = sanitize_value($5)
        pools[$1][:dedup_factor] = sanitize_value($6)
        pools[$1][:health] = sanitize_value($7)
        pools[$1][:zpool_version] = sanitize_value($8)
      end
    end
  rescue Ohai::Exceptions::Exec
    Ohai::Log.debug('Plugin Zpools: Could not shell_out "zpool list -H -o name,size,alloc,free,cap,dedup,health,version". Skipping plugin.')
  end
  pools
end
generate_device_view(fs) click to toggle source
# File lib/ohai/plugins/filesystem.rb, line 65
def generate_device_view(fs)
  view = {}
  fs.each_value do |entry|
    view[entry[:device]] ||= Mash.new
    entry.each do |key, val|
      next if %w{device mount}.include?(key)

      view[entry[:device]][key] = val
    end
    view[entry[:device]][:mounts] ||= []
    if entry[:mount]
      view[entry[:device]][:mounts] << entry[:mount]
    end
  end
  view
end
generate_mountpoint_view(fs) click to toggle source
# File lib/ohai/plugins/filesystem.rb, line 82
def generate_mountpoint_view(fs)
  view = {}
  fs.each_value do |entry|
    next unless entry[:mount]

    view[entry[:mount]] ||= Mash.new
    entry.each do |key, val|
      next if %w{mount device}.include?(key)

      view[entry[:mount]][key] = val
    end
    view[entry[:mount]][:devices] ||= []
    if entry[:device]
      view[entry[:mount]][:devices] << entry[:device]
    end
  end
  view
end
get_alibaba_values() click to toggle source
# File lib/ohai/plugins/cloud.rb, line 130
def get_alibaba_values
  @cloud_attr_obj.add_ipv4_addr(alibaba["meta_data"]["eipv4"], :public)
  @cloud_attr_obj.add_ipv4_addr(alibaba["meta_data"]["private_ipv4"], :private)
  @cloud_attr_obj.local_hostname = alibaba["meta_data"]["hostname"]
  @cloud_attr_obj.provider = "alibaba"
end
get_azure_values() click to toggle source

Fill cloud hash with azure values

# File lib/ohai/plugins/cloud.rb, line 287
def get_azure_values
  azure["metadata"]["network"]["public_ipv4"].each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :public) }
  azure["metadata"]["network"]["public_ipv6"].each { |ipaddr| @cloud_attr_obj.add_ipv6_addr(ipaddr, :public) }
  azure["metadata"]["network"]["local_ipv4"].each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :private) }
  azure["metadata"]["network"]["local_ipv6"].each { |ipaddr| @cloud_attr_obj.add_ipv6_addr(ipaddr, :private) }
  @cloud_attr_obj.public_hostname = azure["public_fqdn"]
  @cloud_attr_obj.provider = "azure"
end
get_digital_ocean_values() click to toggle source

Fill cloud hash with digital_ocean values

# File lib/ohai/plugins/cloud.rb, line 310
def get_digital_ocean_values
  @cloud_attr_obj.add_ipv4_addr(digital_ocean["interfaces"]["public"][0]["ipv4"]["ip_address"], :public) rescue NoMethodError
  @cloud_attr_obj.add_ipv4_addr(digital_ocean["interfaces"]["private"][0]["ipv4"]["ip_address"], :private) rescue NoMethodError
  @cloud_attr_obj.add_ipv6_addr(digital_ocean["interfaces"]["public"][0]["ipv6"]["ip_address"], :public) rescue NoMethodError
  @cloud_attr_obj.add_ipv6_addr(digital_ocean["interfaces"]["private"][0]["ipv6"]["ip_address"], :private) rescue NoMethodError
  @cloud_attr_obj.provider = "digital_ocean"
end
get_dmi_property(dmi, thing) click to toggle source
# File lib/ohai/plugins/shard.rb, line 23
def get_dmi_property(dmi, thing)
  %w{system base_board chassis}.each do |section|
    if dmi[section] && dmi[section][thing] && !dmi[section][thing].strip.empty?
      return dmi[section][thing]
    end
  end
  Ohai::Log.error("shard_seed: Failed to get dmi property #{thing}: is dmidecode installed?")
  raise "Failed to generate shard_seed"
end
get_domain_data() click to toggle source
# File lib/ohai/plugins/libvirt.rb, line 51
def get_domain_data
  domain_data = Mash.new
  virtconn.list_domains.each do |d|
    dv = virtconn.lookup_domain_by_id d
    domain_data[dv.name] = Mash.new
    domain_data[dv.name][:id] = d
    %w{os_type uuid}.each { |a| domain_data[dv.name][a] = dv.send(a) }
    %w{cpu_time max_mem memory nr_virt_cpu state}.each { |a| domain_data[dv.name][a] = dv.info.send(a) }
  end
  domain_data
end
get_ec2_values() click to toggle source

Fill cloud hash with ec2 values

# File lib/ohai/plugins/cloud.rb, line 176
def get_ec2_values
  @cloud_attr_obj.add_ipv4_addr(ec2["public_ipv4"], :public)
  @cloud_attr_obj.add_ipv4_addr(ec2["local_ipv4"], :private)
  @cloud_attr_obj.public_hostname = ec2["public_hostname"]
  @cloud_attr_obj.local_hostname = ec2["local_hostname"]
  @cloud_attr_obj.provider = "ec2"
end
get_eucalyptus_values() click to toggle source
# File lib/ohai/plugins/cloud.rb, line 243
def get_eucalyptus_values
  @cloud_attr_obj.add_ipv4_addr(eucalyptus["public_ipv4"], :public)
  @cloud_attr_obj.add_ipv4_addr(eucalyptus["local_ipv4"], :private)
  @cloud_attr_obj.public_hostname = eucalyptus["public_hostname"]
  @cloud_attr_obj.local_hostname = eucalyptus["local_hostname"]
  @cloud_attr_obj.provider = "eucalyptus"
end
get_gce_values() click to toggle source
# File lib/ohai/plugins/cloud.rb, line 145
def get_gce_values
  public_ips = gce["instance"]["networkInterfaces"].collect do |interface|
    if interface.key?("accessConfigs")
      interface["accessConfigs"].collect { |ac| ac["externalIp"] unless ac["externalIp"] == "" }
    end
  end.flatten.compact

  private_ips = gce["instance"]["networkInterfaces"].filter_map do |interface|
    interface["ip"]
  end

  public_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :public) }
  private_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :private) }
  @cloud_attr_obj.local_hostname = gce["instance"]["hostname"]
  @cloud_attr_obj.provider = "gce"
end
get_global_ipv6_address(name, eth) click to toggle source

Names rackspace ipv6 address for interface

Parameters

name<Symbol>

Use :public_ip or :private_ip

eth<Symbol>

Interface name of public or private ip

# File lib/ohai/plugins/rackspace.rb, line 89
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_instance_id() click to toggle source

Get the rackspace instance_id

# File lib/ohai/plugins/rackspace.rb, line 115
def get_instance_id
  so = shell_out("xenstore-read name")
  if so.exitstatus == 0
    rackspace[:instance_id] = so.stdout.gsub(/instance-/, "")
  end
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin Rackspace: Unable to find xenstore-read, cannot capture instance ID information for Rackspace cloud")
  nil
end
get_ip_address(name, eth) click to toggle source

Alters linode mash with new interface based on name parameter

@param [Symbol] name Ohai name (e.g. :public_ip) @param [Symbol] eth Interface name (e.g. :eth0)

# File lib/ohai/plugins/linode.rb, line 53
def get_ip_address(name, eth)
  if ( eth_iface = network[:interfaces][eth] )
    eth_iface[:addresses].each do |key, info|
      linode[name] = key if info["family"] == "inet"
    end
  end
end
get_java_info() click to toggle source
# File lib/ohai/plugins/java.rb, line 24
def get_java_info
  so = shell_out("java -mx64m -version")
  # Sample output:
  # java version "1.8.0_60"
  # Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
  # Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
  if so.exitstatus == 0
    java = Mash.new
    so.stderr.split(/\r?\n/).each do |line|
      case line
      when /(?:java|openjdk) version \"([0-9\.\_]+)\"/
        java[:version] = $1
      when /^(.+Runtime Environment.*) \((build)\s*(.+)\)$/
        java[:runtime] = { "name" => $1, "build" => $3 }
      when /^(.+ (Client|Server) VM) \(build\s*(.+)\)$/
        java[:hotspot] = { "name" => $1, "build" => $3 }
      end
    end

    languages[:java] = java unless java.empty?
  end
rescue Ohai::Exceptions::Exec
  logger.trace('Plugin Java: Could not shell_out "java -mx64m -version". Skipping plugin')
end
get_linode_values() click to toggle source

Fill cloud hash with linode values

# File lib/ohai/plugins/cloud.rb, line 222
def get_linode_values
  @cloud_attr_obj.add_ipv4_addr(linode["public_ip"], :public)
  @cloud_attr_obj.add_ipv4_addr(linode["private_ip"], :private)
  @cloud_attr_obj.public_hostname = linode["public_hostname"]
  @cloud_attr_obj.local_hostname = linode["local_hostname"]
  @cloud_attr_obj.provider = "linode"
end
get_mac_address(addresses) click to toggle source

returns the mac address from the collection of all address types

# File lib/ohai/plugins/eucalyptus.rb, line 35
def get_mac_address(addresses)
  detected_addresses = addresses.detect { |address, keypair| keypair == { "family" => "lladdr" } }
  if detected_addresses
    detected_addresses.first
  else
    ""
  end
end
get_mac_for_interface(interfaces, interface) click to toggle source

returns the macaddress for interface from a hash of interfaces (iface elsewhere in this file)

# File lib/ohai/plugins/linux/network.rb, line 529
def get_mac_for_interface(interfaces, interface)
  interfaces[interface][:addresses].find { |k, v| v["family"] == "lladdr" }.first unless interfaces[interface][:addresses].nil? || interfaces[interface][:flags].include?("NOARP")
end
get_network_data() click to toggle source
# File lib/ohai/plugins/libvirt.rb, line 63
def get_network_data
  network_data = Mash.new
  virtconn.list_networks.each do |n|
    nv = virtconn.lookup_network_by_name n
    network_data[n] = Mash.new
    %w{bridge_name uuid}.each { |a| network_data[n][a] = nv.send(a) }
  end
  network_data
end
get_node_data() click to toggle source
# File lib/ohai/plugins/libvirt.rb, line 44
def get_node_data
  node_data = Mash.new
  ni = virtconn.node_get_info
  %w{cores cpus memory mhz model nodes sockets threads}.each { |a| node_data[a] = ni.send(a) }
  node_data
end
get_openstack_values() click to toggle source

Fill cloud hash with openstack values

# File lib/ohai/plugins/cloud.rb, line 265
def get_openstack_values
  @cloud_attr_obj.add_ipv4_addr(openstack["public_ipv4"], :public)
  @cloud_attr_obj.add_ipv4_addr(openstack["local_ipv4"], :private)
  @cloud_attr_obj.public_hostname = openstack["public_hostname"]
  @cloud_attr_obj.local_hostname = openstack["local_hostname"]
  @cloud_attr_obj.provider = openstack["provider"]
end
get_private_networks() click to toggle source

Get the rackspace private networks

# File lib/ohai/plugins/rackspace.rb, line 127
def get_private_networks
  so = shell_out("xenstore-ls vm-data/networking")
  if so.exitstatus == 0
    networks = []
    so.stdout.split("\n").map { |l| l.split("=").first.strip }.map do |item|
      so = shell_out("xenstore-read vm-data/networking/#{item}")
      if so.exitstatus == 0
        networks.push(FFI_Yajl::Parser.new.parse(so.stdout))
      else
        logger.trace("Plugin Rackspace: Unable to capture custom private networking information for Rackspace cloud")
        return false
      end
    end
    # these networks are already known to ohai, and are not 'private networks'
    networks.delete_if { |hash| hash["label"] == "private" }
    networks.delete_if { |hash| hash["label"] == "public" }
  end
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin Rackspace: Unable to capture custom private networking information for Rackspace cloud")
  nil
end
get_rackspace_values() click to toggle source

Fill cloud hash with rackspace values

# File lib/ohai/plugins/cloud.rb, line 198
def get_rackspace_values
  @cloud_attr_obj.add_ipv4_addr(rackspace["public_ipv4"], :public)
  @cloud_attr_obj.add_ipv4_addr(rackspace["local_ipv4"], :private)
  @cloud_attr_obj.add_ipv6_addr(rackspace["public_ipv6"], :public)
  @cloud_attr_obj.add_ipv6_addr(rackspace["local_ipv6"], :private)
  @cloud_attr_obj.public_hostname = rackspace["public_hostname"]
  @cloud_attr_obj.local_hostname = rackspace["local_hostname"]
  @cloud_attr_obj.provider = "rackspace"
end
get_redhatish_platform(contents) click to toggle source

@deprecated

# File lib/ohai/plugins/linux/platform.rb, line 25
def get_redhatish_platform(contents)
  contents[/^Red Hat/i] ? "redhat" : contents[/(\w+)/i, 1].downcase
end
get_redhatish_version(contents) click to toggle source

See rubular.com/r/78c1yXYa7zDhdV for example matches

@param contents [String] the contents of /etc/redhat-release

@returns [String] the version string

# File lib/ohai/plugins/linux/platform.rb, line 35
def get_redhatish_version(contents)
  contents[/(release)? ([\d\.]+)/, 2]
end
get_region() click to toggle source

Get the rackspace region

# File lib/ohai/plugins/rackspace.rb, line 101
def get_region
  so = shell_out("xenstore-ls vm-data/provider_data")
  if so.exitstatus == 0
    so.stdout.split("\n").each do |line|
      rackspace[:region] = line.split[2].delete('\"') if /^region/.match?(line)
    end
  end
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin Rackspace: Unable to find xenstore-ls, cannot capture region information for Rackspace cloud")
  nil
end
get_softlayer_values() click to toggle source

Fill cloud hash with softlayer values

# File lib/ohai/plugins/cloud.rb, line 332
def get_softlayer_values
  @cloud_attr_obj.add_ipv4_addr(softlayer["public_ipv4"], :public)
  @cloud_attr_obj.add_ipv4_addr(softlayer["local_ipv4"], :private)
  @cloud_attr_obj.public_hostname = softlayer["public_fqdn"]
  @cloud_attr_obj.provider = "softlayer"
end
get_storage_data() click to toggle source
# File lib/ohai/plugins/libvirt.rb, line 73
def get_storage_data
  storage_data = Mash.new
  virtconn.list_storage_pools.each do |pool|
    sp = virtconn.lookup_storage_pool_by_name pool
    storage_data[pool] = Mash.new
    %w{autostart uuid}.each { |a| storage_data[pool][a] = sp.send(a) }
    %w{allocation available capacity state}.each { |a| storage_data[pool][a] = sp.info.send(a) }

    storage_data[pool][:volumes] = Mash.new
    sp.list_volumes.each do |v|
      storage_data[pool][:volumes][v] = Mash.new
      sv = sp.lookup_volume_by_name v
      %w{key name path}.each { |a| storage_data[pool][:volumes][v][a] = sv.send(a) }
      %w{allocation capacity type}.each { |a| storage_data[pool][:volumes][v][a] = sv.info.send(a) }
    end
  end
  storage_data
end
get_vm_attributes(vmtools_path) click to toggle source
# File lib/ohai/plugins/vmware.rb, line 43
def get_vm_attributes(vmtools_path)
  if !file_exist?(vmtools_path)
    logger.trace("Plugin VMware: #{vmtools_path} not found")
  else
    vmware Mash.new
    begin
      # vmware-toolbox-cmd stat <param> commands
      # Iterate through each parameter supported by the "vwware-toolbox-cmd stat" command, assign value
      # to attribute "vmware[:<parameter>]"
      %w{hosttime speed sessionid balloon swap memlimit memres cpures cpulimit}.each do |param|
        vmware[param] = from_cmd("#{vmtools_path} stat #{param}")
        if /UpdateInfo failed/.match?(vmware[param])
          vmware[param] = nil
        end
      end
      # vmware-toolbox-cmd <param> status commands
      # Iterate through each parameter supported by the "vmware-toolbox-cmd status" command, assign value
      # to attribute "vmware[:<parameter>]"
      %w{upgrade timesync}.each do |param|
        vmware[param] = from_cmd("#{vmtools_path} #{param} status")
      end
    rescue
      logger.trace("Plugin VMware: Error while collecting VMware guest attributes")
    end
  end
end
habitat_binary() click to toggle source
# File lib/ohai/plugins/habitat.rb, line 22
def habitat_binary
  @habitat_binary ||= which("hab")
end
has_ali_dmi?() click to toggle source

look for alibaba string in dmi sys_vendor data within the sys tree. this works even if the system lacks dmidecode use by the Dmi plugin @return [Boolean] do we have Alibaba DMI data?

# File lib/ohai/plugins/alibaba.rb, line 35
def has_ali_dmi?
  if /Alibaba/.match?(file_val_if_exists("/sys/class/dmi/id/sys_vendor"))
    logger.trace("Plugin Alibaba: has_ali_dmi? == true")
    true
  else
    logger.trace("Plugin Alibaba: has_ali_dmi? == false")
    false
  end
end
has_dhcp_option_245?() click to toggle source
# File lib/ohai/plugins/azure.rb, line 57
def has_dhcp_option_245?
  has_245 = false
  if file_exist?("/var/lib/dhcp/dhclient.eth0.leases")
    file_open("/var/lib/dhcp/dhclient.eth0.leases").each do |line|
      if /unknown-245/.match?(line)
        logger.trace("Plugin Azure: Found unknown-245 DHCP option used by Azure.")
        has_245 = true
        break
      end
    end
  end
  has_245
end
has_do_dmi?() click to toggle source

look for digitalocean string in dmi bios data

# File lib/ohai/plugins/digital_ocean.rb, line 31
def has_do_dmi?
  begin
    # detect a vendor of "DigitalOcean"
    if dmi[:bios][:all_records][0][:Vendor] == "DigitalOcean"
      logger.trace("Plugin DigitalOcean: has_do_dmi? == true")
      return true
    end
  rescue NoMethodError
    # dmi[:bios][:all_records][0][:Vendor] may not exist
  end
  logger.trace("Plugin DigitalOcean: has_do_dmi? == false")
  false
end
has_ec2_amazon_dmi?() click to toggle source

look for amazon string in dmi vendor bios data within the sys tree. this works even if the system lacks dmidecode use by the Dmi plugin this gets us detection of new Xen-less HVM instances that are within a VPC @return [Boolean] do we have Amazon DMI data?

# File lib/ohai/plugins/ec2.rb, line 42
def has_ec2_amazon_dmi?
  # detect a version of '4.2.amazon'
  if /Amazon/.match?(file_val_if_exists("/sys/class/dmi/id/bios_vendor"))
    logger.trace("Plugin EC2: has_ec2_amazon_dmi? == true")
    true
  else
    logger.trace("Plugin EC2: has_ec2_amazon_dmi? == false")
    false
  end
end
has_ec2_identifying_number?() click to toggle source

looks at the identifying number WMI value to see if it starts with ec2. this is actually the same value we're looking at in has_ec2_xen_uuid? on linux hosts @return [Boolean] do we have a Xen Identifying Number or not?

# File lib/ohai/plugins/ec2.rb, line 83
def has_ec2_identifying_number?
  if RUBY_PLATFORM.match?(/mswin|mingw32|windows/)
    require "wmi-lite/wmi" unless defined?(WmiLite::Wmi)
    wmi = WmiLite::Wmi.new
    if /^ec2/.match?(wmi.first_of("Win32_ComputerSystemProduct")["identifyingnumber"])
      logger.trace("Plugin EC2: has_ec2_identifying_number? == true")
      true
    end
  else
    logger.trace("Plugin EC2: has_ec2_identifying_number? == false")
    false
  end
end
has_ec2_xen_dmi?() click to toggle source

look for amazon string in dmi bios version data within the sys tree. this works even if the system lacks dmidecode use by the Dmi plugin this gets us detection of HVM instances that are within a VPC @return [Boolean] do we have Amazon DMI data?

# File lib/ohai/plugins/ec2.rb, line 57
def has_ec2_xen_dmi?
  # detect a version of '4.2.amazon'
  if /amazon/.match?(file_val_if_exists("/sys/class/dmi/id/bios_version"))
    logger.trace("Plugin EC2: has_ec2_xen_dmi? == true")
    true
  else
    logger.trace("Plugin EC2: has_ec2_xen_dmi? == false")
    false
  end
end
has_ec2_xen_uuid?() click to toggle source

looks for a xen UUID that starts with ec2 from within the Linux sys tree @return [Boolean] do we have a Xen UUID or not?

# File lib/ohai/plugins/ec2.rb, line 70
def has_ec2_xen_uuid?
  if /^ec2/.match?(file_val_if_exists("/sys/hypervisor/uuid"))
    logger.trace("Plugin EC2: has_ec2_xen_uuid? == true")
    return true
  end
  logger.trace("Plugin EC2: has_ec2_xen_uuid? == false")
  false
end
has_euca_mac?() click to toggle source

detect if the mac address starts with d0:0d

# File lib/ohai/plugins/eucalyptus.rb, line 45
def has_euca_mac?
  network[:interfaces].each_value do |iface|
    mac = get_mac_address(iface[:addresses])
    if MAC_MATCH.match?(mac)
      logger.trace("Plugin Eucalyptus: has_euca_mac? == true (#{mac})")
      return true
    end
  end

  logger.trace("Plugin Eucalyptus: has_euca_mac? == false")
  false
end
has_gce_dmi?() click to toggle source

look for GCE string in dmi vendor bios data within the sys tree. this works even if the system lacks dmidecode use by the Dmi plugin @return [Boolean] do we have Google Compute Engine DMI data?

# File lib/ohai/plugins/gce.rb, line 30
def has_gce_dmi?
  if /Google Compute Engine/.match?(file_val_if_exists("/sys/class/dmi/id/product_name"))
    logger.trace("Plugin GCE: has_gce_dmi? == true")
    true
  else
    logger.trace("Plugin GCE: has_gce_dmi? == false")
    false
  end
end
has_gce_system_info?() click to toggle source

looks at the Manufacturer and Model WMI values to see if they starts with Google. @return [Boolean] Are the manufacturer and model Google?

# File lib/ohai/plugins/gce.rb, line 51
def has_gce_system_info?
  if RUBY_PLATFORM.match?(/mswin|mingw32|windows/)
    require "wmi-lite/wmi" unless defined?(WmiLite::Wmi)
    wmi = WmiLite::Wmi.new
    computer_system = wmi.first_of("Win32_ComputerSystem")
    if computer_system["Manufacturer"] =~ /^Google/ && computer_system["Model"] =~ /^Google/
      logger.trace("Plugin GCE: has_gce_system_info? == true")
      true
    end
  else
    logger.trace("Plugin GCE: has_gce_system_info? == false")
    false
  end
end
has_linode_apt_repos?() click to toggle source

Checks for linode mirrors in the apt sources.list file

@return [Boolean]

# File lib/ohai/plugins/linode.rb, line 36
def has_linode_apt_repos?
  file_exist?("/etc/apt/sources.list") && file_read("/etc/apt/sources.list").include?("linode")
end
has_linode_domain?() click to toggle source

Checks to see if the node is in the members.linode.com domain

@return [Boolean]

# File lib/ohai/plugins/linode.rb, line 28
def has_linode_domain?
  domain&.include?("linode")
end
has_rackspace_kernel?() click to toggle source

Checks for matching rackspace kernel name

Return

true

If kernel name matches

false

Otherwise

# File lib/ohai/plugins/rackspace.rb, line 28
def has_rackspace_kernel?
  kernel[:release].end_with?("-rscloud")
end
has_rackspace_manufacturer?() click to toggle source

Checks for the rackspace manufacturer on Windows

Return

true

If the rackspace cloud can be identified

false

Otherwise

# File lib/ohai/plugins/rackspace.rb, line 50
def has_rackspace_manufacturer?
  return false unless RUBY_PLATFORM.match?(/mswin|mingw32|windows/)

  require "wmi-lite/wmi" unless defined?(WmiLite::Wmi)
  wmi = WmiLite::Wmi.new
  if wmi.first_of("Win32_ComputerSystem")["PrimaryOwnerName"] == "Rackspace"
    logger.trace("Plugin Rackspace: has_rackspace_manufacturer? == true")
    true
  end
end
has_rackspace_metadata?() click to toggle source

Checks for rackspace provider attribute

Return

true

If rackspace provider attribute found

false

Otherwise

# File lib/ohai/plugins/rackspace.rb, line 37
def has_rackspace_metadata?
  so = shell_out("xenstore-read vm-data/provider_data/provider")
  if so.exitstatus == 0
    so.stdout.strip.casecmp("rackspace") == 0
  end
rescue Ohai::Exceptions::Exec
  false
end
has_real_java?() click to toggle source

On Mac OS X, the development tools include “stubs” for JVM executables that prompt the user to install the JVM if they desire. In our case we simply wish to detect if the JVM is there and do not want to trigger a popup window. As a workaround, we can run the java_home executable and check its exit status to determine if the `java` executable is the real one or the OS X stub. In the terminal, it looks like this:

$ /usr/libexec/java_home
Unable to find any JVMs matching version "(null)".
No Java runtime present, try --request to install.

$ echo $?
1

This check always returns true when not on darwin because it is just a workaround for this particular annoyance.

# File lib/ohai/plugins/java.rb, line 65
def has_real_java?
  return true unless on_darwin?

  shell_out("/usr/libexec/java_home").status.success?
end
has_reddog_dhcp_domain?() click to toggle source
# File lib/ohai/plugins/azure.rb, line 71
def has_reddog_dhcp_domain?
  tcp_ip_dhcp_domain == "reddog.microsoft.com"
end
has_scaleway_cmdline?() click to toggle source

looks for `scaleway` keyword in kernel command line @return [Boolean] do we have the keyword or not?

# File lib/ohai/plugins/scaleway.rb, line 29
def has_scaleway_cmdline?
  if file_exist?("/proc/cmdline") && /scaleway/.match?(file_read("/proc/cmdline"))
    logger.trace("Plugin Scaleway: has_scaleway_cmdline? == true")
    return true
  end
  logger.trace("Plugin Scaleway: has_scaleway_cmdline? == false")
  false
end
has_waagent?() click to toggle source

check for either the waagent or the unknown-245 DHCP option that Azure uses blog.mszcool.com/index.php/2015/04/detecting-if-a-virtual-machine-runs-in-microsoft-azure-linux-windows-to-protect-your-software-when-distributed-via-the-azure-marketplace/

# File lib/ohai/plugins/azure.rb, line 50
def has_waagent?
  if file_exist?("/usr/sbin/waagent") || dir_exist?("C:\\WindowsAzure")
    logger.trace("Plugin Azure: Found waagent used by Azure.")
    true
  end
end
init_kernel() click to toggle source

common initial kernel attribute values @return [Mash] basic kernel properties from uname

# File lib/ohai/plugins/kernel.rb, line 31
def init_kernel
  kernel Mash.new
  [["uname -s", :name], ["uname -r", :release],
   ["uname -v", :version], ["uname -m", :machine],
   ["uname -p", :processor]].each do |cmd, property|
     so = shell_out(cmd)
     kernel[property] = so.stdout.strip
   end
  kernel
end
initialize_metadata_mash_compute() click to toggle source

create the basic structure we'll store our data in

# File lib/ohai/plugins/azure.rb, line 92
def initialize_metadata_mash_compute
  metadata = Mash.new
  metadata["compute"] = Mash.new
  metadata
end
initialize_metadata_mash_network(metadata) click to toggle source
# File lib/ohai/plugins/azure.rb, line 98
def initialize_metadata_mash_network(metadata)
  metadata["network"] = Mash.new
  metadata["network"]["interfaces"] = Mash.new
  %w{public_ipv4 local_ipv4 public_ipv6 local_ipv6}.each do |type|
    metadata["network"][type] = []
  end
  metadata
end
interface_code(int_idx, idx) click to toggle source

Returns interface code for an interface

Interface Index (if present, Index otherwise) will be converted in hexadecimal format

@param int_idx [String or nil] the interface index of interface @param idx [String] the index of interface

@return [String]

@example Interface Code when interface index is present

plugin.interface_code("1", "1") #=> "ox1"

@example Interface Code when interface index is not present

plugin.interface_code(nil, "2") #=> "ox2"
# File lib/ohai/plugins/windows/network.rb, line 73
def interface_code(int_idx, idx)
  sprintf("0x%x", (int_idx || idx)).downcase
end
interface_has_no_addresses_in_family?(iface, family) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 542
def interface_has_no_addresses_in_family?(iface, family)
  return true if iface[:addresses].nil?

  iface[:addresses].values.all? { |addr| addr["family"] != family }
end
interface_have_address?(iface, address) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 548
def interface_have_address?(iface, address)
  return false if iface[:addresses].nil?

  iface[:addresses].key?(address)
end
interface_valid_for_route?(iface, address, family) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 558
def interface_valid_for_route?(iface, address, family)
  return true if interface_has_no_addresses_in_family?(iface, family)

  interface_have_address?(iface, address) && interface_address_not_link_level?(iface, address)
end
ioreg_exists?() click to toggle source
# File lib/ohai/plugins/darwin/virtualization.rb, line 34
def ioreg_exists?
  which("ioreg")
end
ipv6_enabled?() click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 38
def ipv6_enabled?
  file_exist? "/proc/net/if_inet6"
end
is_openvz?() click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 46
def is_openvz?
  @openvz ||= file_directory?("/proc/vz")
end
is_openvz_host?() click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 50
def is_openvz_host?
  is_openvz? && file_directory?("/proc/bc")
end
legacy_platform_detection() click to toggle source

modern linux distros include a /etc/os-release file, which we now rely on for OS detection. For older distros that do not include that file we fall back to our pre-Ohai 15 detection logic, which is the method below. No new functionality should be added to this logic.

@deprecated

# File lib/ohai/plugins/linux/platform.rb, line 183
def legacy_platform_detection
  # platform [ and platform_version ? ] should be lower case to avoid dealing with RedHat/Redhat/redhat matching
  if file_exist?("/etc/oracle-release")
    contents = file_read("/etc/oracle-release").chomp
    platform "oracle"
    platform_version get_redhatish_version(contents)
  elsif file_exist?("/etc/enterprise-release")
    contents = file_read("/etc/enterprise-release").chomp
    platform "oracle"
    platform_version get_redhatish_version(contents)
  elsif file_exist?("/etc/f5-release")
    platform "bigip"
    platform_version bigip_version
  elsif file_exist?("/etc/debian_version")
    # Ubuntu and Debian both have /etc/debian_version
    # Ubuntu should always have a working lsb, debian does not by default
    if /Ubuntu/i.match?(lsb[:id])
      platform "ubuntu"
      platform_version lsb[:release]
    else
      platform "debian"
      platform_version file_read("/etc/debian_version").chomp
    end
  elsif file_exist?("/etc/parallels-release")
    contents = file_read("/etc/parallels-release").chomp
    platform get_redhatish_platform(contents)
    platform_version contents.match(/(\d\.\d\.\d)/)[0]
  elsif file_exist?("/etc/Eos-release")
    platform "arista_eos"
    platform_version file_read("/etc/Eos-release").strip.split[-1]
  elsif file_exist?("/etc/redhat-release")
    contents = file_read("/etc/redhat-release").chomp
    platform get_redhatish_platform(contents)
    platform_version get_redhatish_version(contents)
  elsif file_exist?("/etc/system-release")
    contents = file_read("/etc/system-release").chomp
    platform get_redhatish_platform(contents)
    platform_version get_redhatish_version(contents)
  elsif file_exist?("/etc/SuSE-release")
    suse_release = file_read("/etc/SuSE-release")
    suse_version = suse_release.scan(/VERSION = (\d+)\nPATCHLEVEL = (\d+)/).flatten.join(".")
    suse_version = suse_release[/VERSION = ([\d\.]{2,})/, 1] if suse_version == ""
    platform_version suse_version
    if /^openSUSE/.match?(suse_release)
      # opensuse releases >= 42 are openSUSE Leap
      if platform_version.to_i < 42
        platform "opensuse"
      else
        platform "opensuseleap"
      end
    else
      platform "suse"
    end
  elsif os_release_file_is_cisco?
    raise "unknown Cisco /etc/os-release or /etc/cisco-release ID_LIKE field" if
      os_release_info["ID_LIKE"].nil? || !os_release_info["ID_LIKE"].include?("wrlinux")

    case os_release_info["ID"]
    when "nexus"
      platform "nexus"
    when "ios_xr"
      platform "ios_xr"
    else
      raise "unknown Cisco /etc/os-release or /etc/cisco-release ID field"
    end

    platform_version os_release_info["VERSION"]
  elsif file_exist?("/etc/slackware-version")
    platform "slackware"
    platform_version file_read("/etc/slackware-version").scan(/(\d+|\.+)/).join
  elsif file_exist?("/etc/exherbo-release")
    platform "exherbo"
    # no way to determine platform_version in a rolling release distribution
    # kernel release will be used - ex. 3.13
    platform_version shell_out("/bin/uname -r").stdout.strip
  elsif file_exist?("/usr/lib/os-release")
    contents = file_read("/usr/lib/os-release")
    if /clear-linux-os/.match?(contents) # Clear Linux https://clearlinux.org/
      platform "clearlinux"
      platform_version contents[/VERSION_ID=(\d+)/, 1]
    end
  elsif /RedHat/i.match?(lsb[:id])
    platform "redhat"
    platform_version lsb[:release]
  elsif /Amazon/i.match?(lsb[:id])
    platform "amazon"
    platform_version lsb[:release]
  elsif /ScientificSL/i.match?(lsb[:id])
    platform "scientific"
    platform_version lsb[:release]
  elsif /XenServer/i.match?(lsb[:id])
    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
end
linux_encaps_lookup(encap) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 26
def linux_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
load_habitat_service_via_cli(status_stdout) click to toggle source
# File lib/ohai/plugins/habitat.rb, line 38
def load_habitat_service_via_cli(status_stdout)
  # package                           type        desired  state  elapsed (s)  pid   group
  # core/httpd/2.4.35/20190307151146  standalone  up       up     158169       1410  httpd.default
  @services = []
  status_stdout.each_line do |line|
    fields = line.split(/\s+/)
    next unless fields[0].match?(%r{.*/.*/.*/.*}) # ignore header line

    service = {}
    service[:identity] = fields[0]
    service[:topology] = fields[1]
    service[:state_desired] = fields[2]
    service[:state_actual] = fields[2]
    (@services).push(service)
  end
  @services
end
load_libvirt() click to toggle source
# File lib/ohai/plugins/libvirt.rb, line 33
def load_libvirt
  require "libvirt" # this is the ruby-libvirt gem not the libvirt gem
  logger.trace("Plugin Libvirt: Successfully loaded ruby-libvirt gem")
rescue LoadError
  logger.trace("Plugin Libvirt: Can't load gem ruby-libvirt.")
end
locate_interface(ifaces, ifname, mac) click to toggle source
# File lib/ohai/plugins/darwin/network.rb, line 78
def locate_interface(ifaces, ifname, mac)
  return ifname unless ifaces[ifname].nil?
  # oh well, time to go hunting!
  return ifname.chop if /\*$/.match?(ifname)

  ifaces.each_key do |ifc|
    ifaces[ifc][:addresses].each_key do |addr|
      return ifc if addr.eql? mac
    end
  end

  nil
end
logical_info() click to toggle source

Returns a Mash loaded with logical details

Uses Win32_LogicalDisk and logical_properties to return general details of volumes.

Returns an empty Mash in case of any WMI exception.

@see docs.microsoft.com/en-us/windows/desktop/CIMWin32Prov/win32-logicaldisk

@return [Mash]

# File lib/ohai/plugins/filesystem.rb, line 154
def logical_info
  wmi = WmiLite::Wmi.new("Root\\CIMV2")

  # TODO: We should really be parsing Win32_Volume and Win32_MountPoint.
  disks = wmi.instances_of("Win32_LogicalDisk")
  logical_properties(disks)
rescue WmiLite::WmiException
  Ohai::Log.debug("Unable to access Win32_LogicalDisk. Skipping logical details")
  Mash.new
end
logical_properties(disks) click to toggle source

Refines and calculates logical properties out of given instances.

Note that :device here is the same as Volume name and there for compatibility with other OSes.

@param [WmiLite::Wmi::Instance] disks

@return [Mash] Each drive containing following properties:

* :kb_size (Integer)
* :kb_available (Integer)
* :kb_used (Integer)
* :percent_used (Integer)
* :mount (String)
* :fs_type (String)
* :volume_name (String)
* :device (String)
# File lib/ohai/plugins/filesystem.rb, line 203
def logical_properties(disks)
  properties = Mash.new
  disks.each do |disk|
    property = Mash.new
    # In windows the closest thing we have to a device is the volume name
    # and the "mountpoint" is the drive letter...
    device = disk["volumename"].to_s.downcase
    mount = disk["deviceid"]
    property[:kb_size] = disk["size"] ? disk["size"].to_i / 1000 : 0
    property[:kb_available] = disk["freespace"].to_i / 1000
    property[:kb_used] = property[:kb_size] - property[:kb_available]
    property[:percent_used] = (property[:kb_size] == 0 ? 0 : (property[:kb_used] * 100 / property[:kb_size]))
    property[:mount] = mount
    property[:fs_type] = disk["filesystem"].to_s.downcase
    property[:drive_type] = disk["drivetype"].to_i
    property[:drive_type_string] = DRIVE_TYPE[disk["drivetype"].to_i]
    property[:drive_type_human] = disk["description"].to_s
    property[:volume_name] = disk["volumename"].to_s
    property[:device] = device

    key = "#{device},#{mount}"
    properties[key] = property
  end
  properties
end
looks_like_alibaba?() click to toggle source

a single check that combines all the various detection methods for Alibaba @return [Boolean] Does the system appear to be on Alibaba

# File lib/ohai/plugins/alibaba.rb, line 56
def looks_like_alibaba?
  return true if hint?("alibaba") || has_ali_dmi?
end
looks_like_digital_ocean?() click to toggle source
# File lib/ohai/plugins/digital_ocean.rb, line 45
def looks_like_digital_ocean?
  return true if hint?("digital_ocean")
  return true if has_do_dmi? && can_socket_connect?(Ohai::Mixin::DOMetadata::DO_METADATA_ADDR, 80)

  false
end
looks_like_ec2?() click to toggle source

a single check that combines all the various detection methods for EC2 @return [Boolean] Does the system appear to be on EC2

# File lib/ohai/plugins/ec2.rb, line 108
def looks_like_ec2?
  return true if hint?("ec2")

  # Even if it looks like EC2 try to connect first
  if has_ec2_xen_uuid? || has_ec2_amazon_dmi? || has_ec2_xen_dmi? || has_ec2_identifying_number?
    return true if can_socket_connect?(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80)
  end
end
looks_like_euca?() click to toggle source
# File lib/ohai/plugins/eucalyptus.rb, line 58
def looks_like_euca?
  # Try non-blocking connect so we don't "block" if
  # the metadata service doesn't respond
  hint?("eucalyptus") || has_euca_mac? && can_socket_connect?(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80)
end
looks_like_gce?() click to toggle source

Identifies gce

Return

true

If gce can be identified

false

Otherwise

# File lib/ohai/plugins/gce.rb, line 71
def looks_like_gce?
  return true if hint?("gce")

  if has_gce_dmi? || has_gce_system_info?
    return true if can_socket_connect?(Ohai::Mixin::GCEMetadata::GCE_METADATA_ADDR, 80)
  end
end
looks_like_linode?() click to toggle source

Identifies the linode cloud by preferring the hint, then

@return [Boolean]

# File lib/ohai/plugins/linode.rb, line 44
def looks_like_linode?
  hint?("linode") || has_linode_domain? || has_linode_apt_repos?
end
looks_like_rackspace?() click to toggle source

Identifies the rackspace cloud

Return

true

If the rackspace cloud can be identified

false

Otherwise

# File lib/ohai/plugins/rackspace.rb, line 66
def looks_like_rackspace?
  hint?("rackspace") || has_rackspace_metadata? || has_rackspace_kernel? || has_rackspace_manufacturer?
end
looks_like_scaleway?() click to toggle source

a single check that combines all the various detection methods for Scaleway @return [Boolean] Does the system appear to be on Scaleway

# File lib/ohai/plugins/scaleway.rb, line 40
def looks_like_scaleway?
  return true if hint?("scaleway")
  return true if has_scaleway_cmdline? && can_socket_connect?(Ohai::Mixin::ScalewayMetadata::SCALEWAY_METADATA_ADDR, 80)

  false
end
looks_like_softlayer?() click to toggle source

Identifies the softlayer cloud

Return

true

If the softlayer cloud can be identified

false

Otherwise

# File lib/ohai/plugins/softlayer.rb, line 33
def looks_like_softlayer?
  hint?("softlayer")
end
lxc_version_exists?() click to toggle source
# File lib/ohai/plugins/linux/virtualization.rb, line 27
def lxc_version_exists?
  which("lxc-version") || which("lxc-start")
end
mac_addresses(iface) click to toggle source
# File lib/ohai/plugins/windows/network.rb, line 30
def mac_addresses(iface)
  prop = iface[:configuration][:mac_address] || iface[:instance][:network_addresses]
  [prop].flatten.map { |addr| addr.include?(":") ? addr : addr.scan(/.{1,2}/).join(":") }
end
match_iproute(iface, line, cint) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 432
def match_iproute(iface, line, cint)
  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
  cint
end
merge_info(logical_info, encryption_info) click to toggle source

Merges all the various properties of filesystems

@param [Array<Mash>] disks_info

Array of the Mashes containing disk properties

@return [Mash]

# File lib/ohai/plugins/filesystem.rb, line 255
def merge_info(logical_info, encryption_info)
  fs = Mash.new

  encryption_keys_used = Set.new
  logical_info.each do |key, info|
    if encryption_info[info["mount"]]
      encryption_keys_used.add(info["mount"])
      fs[key] = info.merge(encryption_info[info["mount"]])
    else
      fs[key] = info.dup
    end
  end
  left_enc = encryption_info.reject { |x| encryption_keys_used.include?(x) }
  left_enc.each do |key, info|
    fs[",#{key}"] = info
  end
  fs
end
msft_adapter_data() click to toggle source
# File lib/ohai/plugins/windows/network.rb, line 51
def msft_adapter_data
  data = {}
  wmi = WmiLite::Wmi.new("ROOT/StandardCimv2")
  data[:addresses] = wmi.instances_of("MSFT_NetIPAddress")
  data[:adapters] = wmi.instances_of("MSFT_NetAdapter")
  data
end
network_contains_address(address_to_match, ipaddress, iface) click to toggle source

address_to_match: String ipaddress: IPAddress iface: String

# File lib/ohai/plugins/network.rb, line 124
def network_contains_address(address_to_match, ipaddress, iface)
  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
network_data() click to toggle source
# File lib/ohai/plugins/windows/network.rb, line 35
def network_data
  @network_data ||= begin
    data = {}
    wmi = WmiLite::Wmi.new
    data[:addresses] = wmi.instances_of("Win32_NetworkAdapterConfiguration")

    # If we are running on windows nano or another operating system from the future
    # that does not populate the deprecated win32_* WMI classes, then we should
    # grab data from the newer MSFT_* classes
    return msft_adapter_data if data[:addresses].count == 0

    data[:adapters] = wmi.instances_of("Win32_NetworkAdapter")
    data
  end
end
nova_exists?() click to toggle source
# File lib/ohai/plugins/linux/virtualization.rb, line 31
def nova_exists?
  which("nova")
end
on_alibaba?() click to toggle source
# File lib/ohai/plugins/cloud.rb, line 126
def on_alibaba?
  alibaba != nil
end
on_azure?() click to toggle source

Is current cloud azure?

Return

true

If azure Hash is defined

false

Otherwise

# File lib/ohai/plugins/cloud.rb, line 282
def on_azure?
  azure != nil
end
on_darwin?() click to toggle source
# File lib/ohai/plugins/java.rb, line 71
def on_darwin?
  RUBY_PLATFORM.downcase.include?("darwin")
end
on_digital_ocean?() click to toggle source

Is current cloud digital_ocean?

Return

true

If digital_ocean Mash is defined

false

Otherwise

# File lib/ohai/plugins/cloud.rb, line 305
def on_digital_ocean?
  digital_ocean != nil
end
on_ec2?() click to toggle source

Is current cloud ec2?

Return

true

If ec2 Hash is defined

false

Otherwise

# File lib/ohai/plugins/cloud.rb, line 171
def on_ec2?
  ec2 != nil
end
on_eucalyptus?() click to toggle source

Is current cloud eucalyptus?

Return

true

If eucalyptus Hash is defined

false

Otherwise

# File lib/ohai/plugins/cloud.rb, line 239
def on_eucalyptus?
  eucalyptus != nil
end
on_gce?() click to toggle source
# File lib/ohai/plugins/cloud.rb, line 141
def on_gce?
  gce != nil
end
on_linode?() click to toggle source

Is current cloud linode?

Return

true

If linode Hash is defined

false

Otherwise

# File lib/ohai/plugins/cloud.rb, line 217
def on_linode?
  linode != nil
end
on_openstack?() click to toggle source

Is current cloud openstack-based?

Return

true

If openstack Hash is defined

false

Otherwise

# File lib/ohai/plugins/cloud.rb, line 260
def on_openstack?
  openstack != nil
end
on_rackspace?() click to toggle source

Is current cloud rackspace?

Return

true

If rackspace Hash is defined

false

Otherwise

# File lib/ohai/plugins/cloud.rb, line 193
def on_rackspace?
  rackspace != nil
end
on_softlayer?() click to toggle source

Is current cloud softlayer?

Return

true

If softlayer Hash is defined

false

Otherwise

# File lib/ohai/plugins/cloud.rb, line 327
def on_softlayer?
  softlayer != nil
end
openstack_hint?() click to toggle source

check for the ohai hint and log trace messaging

# File lib/ohai/plugins/openstack.rb, line 38
def openstack_hint?
  if hint?("openstack")
    logger.trace("Plugin Openstack: openstack hint present")
    true
  else
    logger.trace("Plugin Openstack: openstack hint not present")
    false
  end
end
openstack_provider() click to toggle source

dreamhost systems had the dhc-user on them < 2016. We should probably remove all this logic help.dreamhost.com/hc/en-us/articles/228377408-How-to-find-the-default-user-of-an-image

# File lib/ohai/plugins/openstack.rb, line 50
def openstack_provider
  # dream host doesn't support windows so bail early if we're on windows
  return "openstack" if RUBY_PLATFORM.match?(/mswin|mingw32|windows/)

  if Etc::Passwd.entries.map(&:name).include?("dhc-user")
    "dreamhost"
  else
    "openstack"
  end
end
openstack_virtualization?() click to toggle source

use virtualization data

# File lib/ohai/plugins/openstack.rb, line 30
def openstack_virtualization?
  if get_attribute(:virtualization, :systems, :openstack)
    logger.trace("Plugin Openstack: has_openstack_virtualization? == true")
    true
  end
end
os_release_file_is_cisco?() click to toggle source

If /etc/os-release indicates we are Cisco based

@returns [Boolean] if we are Cisco according to /etc/os-release

# File lib/ohai/plugins/linux/platform.rb, line 80
def os_release_file_is_cisco?
  file_exist?("/etc/os-release") && os_release_info["CISCO_RELEASE_INFO"]
end
os_release_info() click to toggle source

Cached /etc/os-release info Hash. Also has logic for Cisco Nexus switches that pulls the chained CISCO_RELEASE_INFO file into the Hash (other distros can also reuse this method safely).

@returns [Hash] the canonical, cached Hash of /etc/os-release info or nil

# File lib/ohai/plugins/linux/platform.rb, line 63
def os_release_info
  @os_release_info ||=
    begin
      os_release_info = read_os_release_info("/etc/os-release")
      cisco_release_info = os_release_info["CISCO_RELEASE_INFO"] if os_release_info
      if cisco_release_info && file_exist?(cisco_release_info)
        os_release_info.merge!(read_os_release_info(cisco_release_info))
      end
      os_release_info
    end
end
os_type_decode(sys_type) click to toggle source

decode the OSType field from WMI Win32_OperatingSystem class msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx @param [Integer] sys_type OSType value from Win32_OperatingSystem @return [String] the human consumable OS type value

# File lib/ohai/plugins/kernel.rb, line 108
def os_type_decode(sys_type)
  case sys_type
  when 18 then "WINNT" # most likely so first
  when 0 then "Unknown"
  when 1 then "Other"
  when 14 then "MSDOS"
  when 15 then "WIN3x"
  when 16 then "WIN95"
  when 17 then "WIN98"
  when 19 then "WINCE"
  end
end
parse_bsd_dmesg() { |cpuinfo, line| ... } click to toggle source
# File lib/ohai/plugins/cpu.rb, line 32
def parse_bsd_dmesg(&block)
  cpuinfo = Mash.new
  cpuinfo["flags"] = []
  file_open("/var/run/dmesg.boot").each do |line|
    case line
    when /CPU:\s+(.+) \(([\d.]+).+\)/
      cpuinfo["model_name"] = $1
      cpuinfo["mhz"] = $2
    when /Features=.+<(.+)>/, /Features2=[a-f\dx]+<(.+)>/
      cpuinfo["flags"].concat($1.downcase.split(","))
      # Features2=0x80000001<SSE3,<b31>>
    else
      yield(cpuinfo, line)
    end
  end
  cpuinfo
end
parse_common_df(out) click to toggle source
# File lib/ohai/plugins/filesystem.rb, line 101
def parse_common_df(out)
  fs = {}
  out.each_line do |line|
    case line
    when /^Filesystem\s+1024-blocks/
      next
    when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/
      key = "#{$1},#{$6}"
      fs[key] = Mash.new
      fs[key][:device] = $1
      fs[key][:kb_size] = $2
      fs[key][:kb_used] = $3
      fs[key][:kb_available] = $4
      fs[key][:percent_used] = $5
      fs[key][:mount] = $6
    end
  end
  fs
end
parse_compatible_versions() click to toggle source
# File lib/ohai/plugins/powershell.rb, line 74
def parse_compatible_versions
  so = shell_out("#{powershell_command} \"#{version_command}\"")
  versions = []
  so.stdout.strip.each_line do |line|
    versions << line.strip
  end
  versions
end
parse_cpuinfo() click to toggle source
# File lib/ohai/plugins/cpu.rb, line 250
def parse_cpuinfo
  cpuinfo = Mash.new
  real_cpu = Mash.new
  cpu_number = 0
  current_cpu = nil

  file_open("/proc/cpuinfo").each_line do |line|
    case line
    when /processor\s+:\s(.+)/
      cpuinfo[$1] = Mash.new
      current_cpu = $1
      cpu_number += 1
    when /vendor_id\s+:\s(.+)/
      vendor_id = $1
      if vendor_id.include?("IBM/S390")
        cpuinfo["vendor_id"] = vendor_id
      else
        cpuinfo[current_cpu]["vendor_id"] = vendor_id
      end
    when /cpu family\s+:\s(.+)/
      cpuinfo[current_cpu]["family"] = $1
    when /model\s+:\s(.+)/
      model = $1
      cpuinfo[current_cpu]["model"] = model
      # ppc has "model" at the end of /proc/cpuinfo. In addition it should always include a include a dash or "IBM".
      # So let's put this in cpu/model on ppc
      cpuinfo["machine_model"] = model if model.match?(/-|IBM/)
    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
    when /BogoMIPS\s+:\s(.+)/
      cpuinfo[current_cpu]["bogomips"] = $1
    when /Features\s+:\s(.+)/
      cpuinfo[current_cpu]["features"] = $1.split
    when /bogomips per cpu:\s(.+)/
      cpuinfo["bogomips_per_cpu"] = $1
    when /features\s+:\s(.+)/
      cpuinfo["features"] = $1.split
    # ppc64le
    when /revision\s+:\s(.+)/
      cpuinfo[current_cpu]["model"] = $1
    when /cpu\s+:\s(.+)/
      cpuinfo[current_cpu]["model_name"] = $1
    when /clock\s+:\s(.+)/
      cpuinfo[current_cpu]["mhz"] = $1
    when /timebase\s+:\s(.+)/
      cpuinfo["timebase"] = $1
    when /platform\s+:\s(.+)/
      cpuinfo["platform"] = $1
    when /machine\s+:\s(.+)/
      cpuinfo["machine"] = $1
    when /firmware\s+:\s(.+)/
      cpuinfo["firmware"] = $1
    when /MMU\s+:\s(.+)/
      cpuinfo["mmu"] = $1
    # s390x
    when /processor\s(\d):\s(.+)/
      current_cpu = $1
      cpu_number += 1
      cpuinfo[current_cpu] = Mash.new
      current_cpu_info = $2.split(",")
      current_cpu_info.each do |i|
        name_value = i.split("=")
        name = name_value[0].strip
        value = name_value[1].strip
        cpuinfo[current_cpu][name] = value
      end
    end
  end

  # use data we collected unless cpuinfo is lacking core information
  # which is the case on older linux distros
  if !real_cpu.empty? && cpuinfo["0"]["cores"]
    logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
    cpuinfo[:real] = real_cpu.keys.length
    cpuinfo[:cores] = real_cpu.keys.length * cpuinfo["0"]["cores"].to_i
  else
    logger.trace("Plugin CPU: real cpu & core data is missing in /proc/cpuinfo and lscpu")
  end
  cpuinfo[:total] = cpu_number
  cpuinfo
end
parse_df_or_mount(shell_out) click to toggle source
# File lib/ohai/plugins/filesystem.rb, line 610
def parse_df_or_mount(shell_out)
  oldie = Mash.new

  shell_out.lines.each do |line|
    fields = line.split
    case line
    # headers and horizontal rules to skip
    when /^\s*(node|---|^Filesystem\s+1024-blocks)/
      next
    # strictly a df entry
    when /^(.+?)\s+([0-9-]+)\s+([0-9-]+)\s+([0-9-]+)\s+([0-9-]+\%*)\s+(.+)$/
      if $1 == "Global"
        dev = "#{$1}:#{$6}"
      else
        dev = $1
      end
      mountpoint = $6
      key = "#{dev},#{mountpoint}"
      oldie[key] ||= Mash.new
      oldie[key][:kb_size] = $2
      oldie[key][:kb_used] = $3
      oldie[key][:kb_available] = $4
      oldie[key][:percent_used] = $5
      oldie[key][:mount] = mountpoint
      oldie[key][:device] = dev
    # an entry starting with 'G' or / (E.G. /tmp or /var)
    when %r{^\s*(G.*?|/\w)}
      if fields[0] == "Global"
        dev = fields[0] + ":" + fields[1]
      else
        dev = fields[0]
      end
      mountpoint = fields[1]
      key = "#{dev},#{mountpoint}"
      oldie[key] ||= Mash.new
      oldie[key][:mount] = mountpoint
      oldie[key][:fs_type] = fields[2]
      oldie[key][:mount_options] = fields[6].split(",")
      oldie[key][:device] = dev
    # entries occupying the 'Node' column parsed here
    else
      dev = fields[0] + ":" + fields[1]
      mountpoint = fields[2]
      key = "#{dev},#{mountpoint}"
      oldie[key] ||= Mash.new
      oldie[key][:mount] = mountpoint
      oldie[key][:device] = dev
      oldie[key][:fs_type] = fields[3]
      oldie[key][:mount_options] = fields[7].split(",")
    end
  end
  oldie
end
parse_ip_addr(iface) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 453
def parse_ip_addr(iface)
  so = shell_out("ip addr")
  cint = nil
  so.stdout.lines do |line|
    cint = match_iproute(iface, line, cint)

    parse_ip_addr_link_line(cint, iface, line)
    cint = parse_ip_addr_inet_line(cint, iface, line)
    parse_ip_addr_inet6_line(cint, iface, line)
  end
end
parse_ip_addr_inet6_line(cint, iface, line) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 512
def parse_ip_addr_inet6_line(cint, iface, line)
  if line =~ %r{inet6 ([a-f0-9\:]+)/(\d+) scope (\w+)( .*)?}
    iface[cint][:addresses] ||= Mash.new
    tmp_addr = $1
    tags = $4 || ""
    tags = tags.split

    iface[cint][:addresses][tmp_addr] = {
      "family" => "inet6",
      "prefixlen" => $2,
      "scope" => ($3.eql?("host") ? "Node" : $3.capitalize),
      "tags" => tags,
    }
  end
end
parse_ip_addr_inet_line(cint, iface, line) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 475
def parse_ip_addr_inet_line(cint, iface, line)
  if line =~ %r{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 # Create the fake alias interface if needed
    iface[cint][:addresses] ||= Mash.new
    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 alias interface, restore cint to its original value
    cint = original_int unless original_int.nil?
  end
  cint
end
parse_line(line, cmdtype) click to toggle source
# File lib/ohai/plugins/filesystem.rb, line 37
def parse_line(line, cmdtype)
  case cmdtype
  when "lsblk"
    regex = /NAME="(\S+).*?" UUID="(\S*)" LABEL="(\S*)" FSTYPE="(\S*)"/
    if line =~ regex
      dev = $1
      dev = find_device(dev) unless dev.start_with?("/")
      uuid = $2
      label = $3
      fs_type = $4
      return { dev: dev, uuid: uuid, label: label, fs_type: fs_type }
    end
  when "blkid"
    bits = line.split
    dev = bits.shift.split(":")[0]
    f = { dev: dev }
    bits.each do |keyval|
      if keyval =~ /(\S+)="(\S+)"/
        key = $1.downcase.to_sym
        key = :fs_type if key == :type
        f[key] = $2
      end
    end
    return f
  end
  nil
end
parse_lscpu(cpu_info) click to toggle source
# File lib/ohai/plugins/cpu.rb, line 63
def parse_lscpu(cpu_info)
  lscpu_info = Mash.new
  begin
    so = shell_out("lscpu")
    cpu_cores = shell_out("lscpu -p=CPU,CORE,SOCKET")
    if so.exitstatus == 0 && cpu_cores.exitstatus == 0
      lscpu_info[:numa_node_cpus] = Mash.new
      lscpu_info[:vulnerability] = Mash.new
      so.stdout.each_line do |line|
        case line
        when /^Architecture:\s+(.+)/
          lscpu_info[:architecture] = $1.to_s
        when /^CPU op-mode\(s\):\s+(.+)/
          lscpu_info[:cpu_opmodes] = $1.split(", ")
        when /^Byte Order:\s+(.+)/
          lscpu_info[:byte_order] = $1.downcase
        when /^Address sizes:\s+(.+)/
          lscpu_info[:address_sizes] = $1.split(", ")
        when /^CPU\(s\):\s+(.+)/
          lscpu_info[:cpus] = $1.to_i
        when /^On-line CPU\(s\) list:\s+(.+)/
          cpu_range = range_str_to_a($1)
          if cpu_range == [0]
            lscpu_info[:cpus_online] = 0
          else
            lscpu_info[:cpus_online] = cpu_range.length
          end
        when /^Off-line CPU\(s\) list:\s+(.+)/
          cpu_range = range_str_to_a($1)
          if cpu_range == [0]
            lscpu_info[:cpus_offline] = 0
          else
            lscpu_info[:cpus_offline] = cpu_range.length
          end
        when /^Thread\(s\) per core:\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
          lscpu_info[:threads_per_core] = $1.to_i
        when /^Core\(s\) per socket:\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
          lscpu_info[:cores_per_socket] = $1.to_i
        when /^Socket\(s\):\s+(.+)/ # http://rubular.com/r/DIzmPtJFvK
          lscpu_info[:sockets] = $1.to_i
        when /^Socket\(s\) per book:\s+(.+)/
          lscpu_info[:sockets_per_book] = $1.to_i
        when /^Book\(s\) per drawer:\s+(.+)/
          lscpu_info[:books_per_drawer] = $1.to_i
        when /^Drawer\(s\):\s+(.+)/
          lscpu_info[:drawers] = $1.to_i
        when /^NUMA node\(s\):\s+(.+)/
          lscpu_info[:numa_nodes] = $1.to_i
        when /^Vendor ID:\s+(.+)/
          lscpu_info[:vendor_id] = $1
        when /^Machine type:\s+(.+)/
          lscpu_info[:machine_type] = $1
        when /^CPU family:\s+(.+)/
          lscpu_info[:family] = $1
        when /^Model:\s+(.+)/
          lscpu_info[:model] = $1
        when /^Model name:\s+(.+)/
          lscpu_info[:model_name] = $1
        when /^Stepping:\s+(.+)/
          lscpu_info[:stepping] = $1
        when /^CPU MHz:\s+(.+)/
          lscpu_info[:mhz] = $1
        when /^CPU static MHz:\s+(.+)/
          lscpu_info[:mhz] = $1
        when /^CPU max MHz:\s+(.+)/
          lscpu_info[:mhz_max] = $1
        when /^CPU min MHz:\s+(.+)/
          lscpu_info[:mhz_min] = $1
        when /^CPU dynamic MHz:\s+(.+)/
          lscpu_info[:mhz_dynamic] = $1
        when /^BogoMIPS:\s+(.+)/
          lscpu_info[:bogomips] = $1
        when /^Virtualization:\s+(.+)/
          lscpu_info[:virtualization] = $1
        when /^Virtualization type:\s+(.+)/
          lscpu_info[:virtualization_type] = $1
        when /^Hypervisor vendor:\s+(.+)/
          lscpu_info[:hypervisor_vendor] = $1
        when /^Dispatching mode:\s+(.+)/
          lscpu_info[:dispatching_mode] = $1
        when /^L1d cache:\s+(.+)/
          lscpu_info[:l1d_cache] = $1
        when /^L1i cache:\s+(.+)/
          lscpu_info[:l1i_cache] = $1
        when /^L2 cache:\s+(.+)/
          lscpu_info[:l2_cache] = $1
        when /^L2d cache:\s+(.+)/
          lscpu_info[:l2d_cache] = $1
        when /^L2i cache:\s+(.+)/
          lscpu_info[:l2i_cache] = $1
        when /^L3 cache:\s+(.+)/
          lscpu_info[:l3_cache] = $1
        when /^L4 cache:\s+(.+)/
          lscpu_info[:l4_cache] = $1
        when /^NUMA node(\d+) CPU\(s\):\s+(.+)/
          numa_node = $1
          cpus = $2
          lscpu_info[:numa_node_cpus][numa_node] = range_str_to_a(cpus)
        when /^Vulnerability (.+?):\s+(.+)/ # https://rubular.com/r/aKtSD1ypUlKbGm
          name = $1.strip.downcase.tr(" ", "_")
          description = $2.strip
          lscpu_info[:vulnerability][name] = Mash.new
          lscpu_info[:vulnerability][name] = description
        when /^Flags:\s+(.+)/
          lscpu_info[:flags] = $1.split(" ").sort
          # flags are "features" on aarch64 and s390x so add it for backwards computability
          lscpu_info[:features] = lscpu_info[:flags] if lscpu_info[:architecture].match?(/aarch64|s390x/)
        end
      end

      case lscpu_info[:architecture]
      when "s390x"
        # Add data from /proc/cpuinfo that isn't available from lscpu
        lscpu_info[:bogomips_per_cpu] = cpu_info[:bogomips_per_cpu]
        lscpu_info[:version] = cpu_info["0"][:version]
        lscpu_info[:identification] = cpu_info["0"][:identification]
        lscpu_info[:machine] = cpu_info["0"][:machine]
        lscpu_total = lscpu_info[:sockets_per_book] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core] * lscpu_info[:books_per_drawer] * lscpu_info[:drawers]
        lscpu_real = lscpu_info[:sockets_per_book]
        lscpu_cores = lscpu_info[:sockets_per_book] * lscpu_info[:cores_per_socket] * lscpu_info[:books_per_drawer] * lscpu_info[:drawers]
      when "ppc64le"
        # Add data from /proc/cpuinfo that isn't available from lscpu
        lscpu_info[:timebase] = cpu_info[:timebase]
        lscpu_info[:platform] = cpu_info[:platform]
        lscpu_info[:machine_model] = cpu_info[:machine_model]
        lscpu_info[:machine] = cpu_info[:machine]
        lscpu_info[:firmware] = cpu_info[:firmware] if cpu_info[:firmware]
        lscpu_info[:mmu] = cpu_info[:mmu] if cpu_info[:mmu]
        lscpu_info[:mhz] = cpu_info["0"][:mhz]
        lscpu_total = lscpu_info[:sockets] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core]
        lscpu_real = lscpu_info[:sockets]
        lscpu_cores = lscpu_info[:sockets] * lscpu_info[:cores_per_socket]
      else
        lscpu_total = lscpu_info[:sockets] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core]
        lscpu_real = lscpu_info[:sockets]
        lscpu_cores = lscpu_info[:sockets] * lscpu_info[:cores_per_socket]
      end

      # Enumerate cpus and fill out data to provide backwards compatibility data
      cpu_cores.stdout.each_line do |line|
        current_cpu = nil
        current_core = nil
        current_socket = nil

        case line
        # skip comments
        when /^#/
          next
        # Parse data from "lscpu -p=CPU,CORE,SOCKET"
        when /(\d+),(\d+),(\d+)/
          current_cpu = $1
          current_core = $2
          current_socket = $3
        end
        lscpu_info[current_cpu] = Mash.new
        lscpu_info[current_cpu][:vendor_id] = lscpu_info[:vendor_id] if lscpu_info[:vendor_id]
        lscpu_info[current_cpu][:family] = lscpu_info[:family] if lscpu_info[:family]
        lscpu_info[current_cpu][:model] = lscpu_info[:model] if lscpu_info[:model]
        lscpu_info[current_cpu][:model_name] = lscpu_info[:model_name] if lscpu_info[:model_name]
        lscpu_info[current_cpu][:stepping] = lscpu_info[:stepping] if lscpu_info[:stepping]
        lscpu_info[current_cpu][:mhz] = lscpu_info[:mhz] if lscpu_info[:mhz]
        lscpu_info[current_cpu][:bogomips] = lscpu_info[:bogomips] if lscpu_info[:bogomips]
        # Per cpu cache_size is only really available from /proc/cpuinfo on x86
        lscpu_info[current_cpu][:cache_size] = cpu_info[current_cpu][:cache_size] if cpu_info[current_cpu] && cpu_info[current_cpu][:cache_size]
        lscpu_info[current_cpu][:physical_id] = current_socket
        lscpu_info[current_cpu][:core_id] = current_core
        lscpu_info[current_cpu][:cores] = lscpu_info[:cores_per_socket].to_s
        lscpu_info[current_cpu][:flags] = lscpu_info[:flags] if lscpu_info[:flags]
        lscpu_info[current_cpu][:features] = lscpu_info[:flags] if lscpu_info[:architecture].match?(/aarch64|s390x/)
        if lscpu_info[:architecture] == "s390x"
          lscpu_info[current_cpu][:version] = cpu_info[current_cpu][:version] if cpu_info[current_cpu][:version]
          lscpu_info[current_cpu][:identification] = cpu_info[current_cpu][:identification] if cpu_info[current_cpu][:identification]
          lscpu_info[current_cpu][:machine] = cpu_info[current_cpu][:machine] if cpu_info[current_cpu][:machine]
        end
      end
      lscpu_info[:total] = lscpu_total
      lscpu_info[:real] = lscpu_real
      lscpu_info[:cores] = lscpu_cores
    else
      logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
    end
  rescue Ohai::Exceptions::Exec # util-linux isn't installed most likely
    logger.trace("Plugin CPU: Error executing lscpu. util-linux may not be installed.")
  end
  lscpu_info
end
parse_media(media_string) click to toggle source
# File lib/ohai/plugins/darwin/network.rb, line 28
def parse_media(media_string)
  media = {}
  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]] = {} unless media.key?(line_array[i])
        if media[line_array[i]].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
      elsif line_array[i].eql?("autoselect")
        media["autoselect"] = {} unless media.key?("autoselect")
        media["autoselect"]["options"] = []
      end
    else
      media["none"] = { "options" => [] }
    end
  end

  media
end
parse_metadata() click to toggle source
# File lib/ohai/plugins/azure.rb, line 116
def parse_metadata
  return nil unless can_socket_connect?(Ohai::Mixin::AzureMetadata::AZURE_METADATA_ADDR, 80)

  endpoint_data = fetch_metadata
  return nil if endpoint_data.nil?

  metadata = initialize_metadata_mash_compute

  # blindly add everything in compute to our data structure
  endpoint_data["compute"].each do |k, v|
    metadata["compute"][k] = v
  end

  # receiving network output is not guaranteed
  unless endpoint_data["network"].nil?
    metadata = initialize_metadata_mash_network(metadata)
    # parse out per interface interface IP data
    endpoint_data["network"]["interface"].each do |int|
      metadata["network"]["interfaces"][int["macAddress"]] = Mash.new
      metadata["network"]["interfaces"][int["macAddress"]]["mac"] = int["macAddress"]
      metadata["network"]["interfaces"][int["macAddress"]]["public_ipv6"] = fetch_ip_data(int, "ipv6", "publicIpAddress")
      metadata["network"]["interfaces"][int["macAddress"]]["public_ipv4"] = fetch_ip_data(int, "ipv4", "publicIpAddress")
      metadata["network"]["interfaces"][int["macAddress"]]["local_ipv6"] = fetch_ip_data(int, "ipv6", "privateIpAddress")
      metadata["network"]["interfaces"][int["macAddress"]]["local_ipv4"] = fetch_ip_data(int, "ipv4", "privateIpAddress")
    end

    # aggregate the total IP data
    %w{public_ipv4 local_ipv4 public_ipv6 local_ipv6}.each do |type|
      metadata["network"]["interfaces"].each_value do |val|
        metadata["network"][type].concat val[type] unless val[type].empty?
      end
    end
  end

  metadata
end
parse_routes(family, iface) click to toggle source

using a temporary var to hold routes and their interface name

# File lib/ohai/plugins/linux/network.rb, line 143
def parse_routes(family, iface)
  iface.filter_map do |i, iv|
    next unless iv[:routes]

    iv[:routes].filter_map do |r|
      r.merge(dev: i) if r[:family] == family[:name]
    end
  end.flatten
end
parse_smp_affinity(path, cpus) click to toggle source

Documentation: www.kernel.org/doc/Documentation/IRQ-affinity.txt format: comma-separate list of 32bit bitmask in hex each bit is a CPU, right to left ordering (i.e. CPU0 is rightmost)

# File lib/ohai/plugins/linux/interrupts.rb, line 28
def parse_smp_affinity(path, cpus)
  masks = file_read(path).strip
  bit_masks = []
  masks.split(",").each do |mask|
    bit_masks << mask.rjust(8, "0").to_i(16).to_s(2)
  end
  affinity_mask = bit_masks.join
  affinity_by_cpu = affinity_mask.split("").reverse
  smp_affinity_by_cpu = Mash.new
  (0..cpus - 1).each do |cpu|
    smp_affinity_by_cpu[cpu] = affinity_by_cpu[cpu].to_i == 1
  end
  smp_affinity_by_cpu
end
pc_system_type_decode(type) click to toggle source

decode the PCSystemType field from WMI Win32_OperatingSystem class msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx @param [Integer] type the integer value from PCSystemType @return [String] the human consumable OS type value

# File lib/ohai/plugins/kernel.rb, line 125
def pc_system_type_decode(type)
  case type
  when 4 then "Enterprise Server" # most likely so first
  when 0 then "Unspecified"
  when 1 then "Desktop"
  when 2 then "Mobile"
  when 3 then "Workstation"
  when 5 then "SOHO Server"
  when 6 then "Appliance PC"
  when 7 then "Performance Server"
  when 8 then "Maximum"
  end
end
platform_family_from_platform(plat) click to toggle source

Determines the platform_family based on the platform

@param plat [String] the platform name

@returns [String] platform_family value

# File lib/ohai/plugins/linux/platform.rb, line 135
def platform_family_from_platform(plat)
  case plat
  when /ubuntu/, /debian/, /linuxmint/, /raspbian/, /cumulus/, /kali/, /pop/
    # apt-get+dpkg almost certainly goes here
    "debian"
  when /centos/, /redhat/, /oracle/, /almalinux/, /rocky/, /scientific/, /enterpriseenterprise/, /xenserver/, /xcp-ng/, /cloudlinux/, /alibabalinux/, /sangoma/, /clearos/, /parallels/, /ibm_powerkvm/, /nexus_centos/, /bigip/, /virtuozzo/ # Note that 'enterpriseenterprise' is oracle's LSB "distributor ID"
    # NOTE: "rhel" should be reserved exclusively for recompiled rhel versions that are nearly perfectly compatible down to the platform_version.
    # The operating systems that are "rhel" should all be as compatible as rhel7 = centos7 = oracle7 = scientific7 (98%-ish core RPM version compatibility
    # and the version numbers MUST track the upstream). The appropriate EPEL version repo should work nearly perfectly.  Some variation like the
    # oracle kernel version differences and tuning and extra packages are clearly acceptable. Almost certainly some distros above (xenserver?)
    # should not be in this list. Please use fedora, below, instead. Also note that this is the only platform_family with this strict of a rule,
    # see the example of the debian platform family for how the rest of the platform_family designations should be used.
    #
    # TODO: when XCP-NG 7.4 support ends we can remove the xcp-ng match. 7.5+ reports as xenenterprise which we remap to xenserver
    "rhel"
  when /amazon/
    "amazon"
  when /suse/, /sles/, /opensuseleap/, /opensuse/, /sled/
    "suse"
  when /fedora/, /arista_eos/
    # In the broadest sense:  RPM-based, fedora-derived distributions which are not strictly re-compiled RHEL (if it uses RPMs, and smells more like redhat and less like
    # SuSE it probably goes here).
    "fedora"
  when /nexus/, /ios_xr/
    "wrlinux"
  when /gentoo/
    "gentoo"
  when /arch/, /manjaro/
    "arch"
  when /exherbo/
    "exherbo"
  when /alpine/
    "alpine"
  when /clearlinux/
    "clearlinux"
  when /mangeia/
    "mandriva"
  when /slackware/
    "slackware"
  end
end
platform_id_remap(id) click to toggle source

our platform names don't match os-release. given a time machine they would but ohai came before the os-release file. This method remaps the os-release names to the ohai names

@param id [String] the platform ID from /etc/os-release

@returns [String] the platform name to use in Ohai

# File lib/ohai/plugins/linux/platform.rb, line 107
def platform_id_remap(id)
  # this catches the centos guest shell in the nexus switch which identifies itself as centos
  return "nexus_centos" if id == "centos" && os_release_file_is_cisco?

  # the platform mappings between the 'ID' field in /etc/os-release and the value
  # ohai uses. If you're adding a new platform here and you want to change the name
  # you'll want to add it here and then add a spec for the platform_id_remap method
  {
    "alinux" => "alibabalinux",
    "amzn" => "amazon",
    "archarm" => "arch",
    "cumulus-linux" => "cumulus",
    "ol" => "oracle",
    "opensuse-leap" => "opensuseleap",
    "rhel" => "redhat",
    "sles_sap" => "suse",
    "sles" => "suse",
    "xenenterprise" => "xenserver",
  }[id.downcase] || id.downcase
end
podman_exists?() click to toggle source
# File lib/ohai/plugins/linux/virtualization.rb, line 39
def podman_exists?
  which("podman")
end
powershell_command() click to toggle source
# File lib/ohai/plugins/powershell.rb, line 65
def powershell_command
  ["powershell.exe",
    "-NoLogo",
    "-NonInteractive",
    "-NoProfile",
    "-Command",
  ].join(" ")
end
prefer_ipv4(addresses) click to toggle source

Returns IPV4 address from list of addresses containing IPV4 and IPV6 formats

@param addresses [Array<String>] List of addresses

@return [String]

@example When list contains both IPV4 and IPV6 formats

plugin.prefer_ipv4([IPV4, IPV6]) #=> "IPV4"

@example When list contains only IPV6 format

plugin.prefer_ipv4([IPV6]) #=> "IPV6"
# File lib/ohai/plugins/windows/network.rb, line 88
def prefer_ipv4(addresses)
  return nil unless addresses.is_a?(Array)

  addresses.find { |ip| IPAddress.valid_ipv4?(ip) } ||
    addresses.find { |ip| IPAddress.valid_ipv6?(ip) }
end
prlctl_exists?() click to toggle source
# File lib/ohai/plugins/darwin/virtualization.rb, line 30
def prlctl_exists?
  which("prlctl")
end
product_type_decode(type) click to toggle source

given the ProductType value from WMI's Win32_OperatingSystem class msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx return either workstation or server @param [Integer] type ProductType value from Win32_OperatingSystem @return [String] Workstation or Server

# File lib/ohai/plugins/kernel.rb, line 98
def product_type_decode(type)
  return "Workstation" if type == 1

  "Server"
end
range_str_to_a(range) click to toggle source

Convert a string that looks like range of CPUs to an array Given the following range: 1-7 Convert it into an array: [1, 2, 3, 4, 5, 6, 7]

# File lib/ohai/plugins/cpu.rb, line 53
def range_str_to_a(range)
  range.split(",").each_with_object([]) do |cpu, arr|
    if /\d+-\d+/.match?(cpu.to_s)
      arr << Range.new(*cpu.split("-").map(&:to_i)).to_a
    else
      arr << cpu.to_i
    end
  end.flatten
end
read_os_release_info(file) click to toggle source

Reads an os-release-info file and parse it into a hash

@param file [String] the filename to read (e.g. '/etc/os-release')

@returns [Hash] the file parsed into a Hash or nil

# File lib/ohai/plugins/linux/platform.rb, line 46
def read_os_release_info(file)
  return nil unless file_exist?(file)

  file_read(file).split.inject({}) do |map, line|
    key, value = line.split("=")
    map[key] = value.gsub(/\A"|"\Z/, "") if value
    map
  end
end
resolve_fqdn() click to toggle source

forward and reverse lookup to canonicalize FQDN (hostname -f equivalent)

# File lib/ohai/plugins/hostname.rb, line 49
def resolve_fqdn
  canonicalize_hostname_with_retries(from_cmd("hostname"))
end
route_is_valid_default_route?(route, default_route) click to toggle source
# File lib/ohai/plugins/linux/network.rb, line 564
def route_is_valid_default_route?(route, default_route)
  # if the route destination is a default route, it's good
  return true if route[:destination] == "default"

  return false if default_route[:via].nil?

  dest_ipaddr = IPAddr.new(route[:destination])
  default_route_via = IPAddr.new(default_route[:via])

  # check if nexthop is the same address family
  return false if dest_ipaddr.ipv4? != default_route_via.ipv4?

  # the default route has a gateway and the route matches the gateway
  dest_ipaddr.include?(default_route_via)
end
run_ruby(command) click to toggle source
# File lib/ohai/plugins/ruby.rb, line 24
def run_ruby(command)
  cmd = "ruby -e \"require 'rbconfig'; #{command}\""
  so = shell_out(cmd)
  so.stdout.strip
end
run_with_check(bin) { || ... } click to toggle source
# File lib/ohai/plugins/filesystem.rb, line 121
def run_with_check(bin, &block)
  yield
rescue Ohai::Exceptions::Exec => e
  unless Ohai.config[:plugin][:filesystem][:allow_partial_data]
    raise e
  end

  logger.warn("Plugin Filesystem: #{bin} binary is not available. Some data will not be available.")
end
sanitize_value(value) click to toggle source

If zpool status doesn't know about a field it returns '-'. We don't want to fill a field with that

# File lib/ohai/plugins/zpools.rb, line 26
def sanitize_value(value)
  value == "-" ? nil : value
end
scope_lookup(scope) click to toggle source
# File lib/ohai/plugins/darwin/network.rb, line 66
def scope_lookup(scope)
  return "Node" if scope.eql?("::1")
  return "Link" if /^fe80\:/.match?(scope)
  return "Site" if /^fec0\:/.match?(scope)

  "Global"
end
server_core?(sku) click to toggle source

given the OperatingSystemSKU value from WMI's Win32_OperatingSystem class msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx return if we're on a Server Core installation @param [String] sku OperatingSystemSKU value from Win32_OperatingSystem @return [boolean]

# File lib/ohai/plugins/kernel.rb, line 61
def server_core?(sku)
  return true if [
    12, # Server Datacenter Core
    39, # Server Datacenter without Hyper-V Core
    14, # Server Enterprise Core
    41, # Server Enterprise without Hyper-V Core
    13, # Server Standard Core
    40, # Server Standard without Hyper-V Core
    63, # Small Business Server Premium Core
    53, # Server Solutions Premium Core
    46, # Storage Server Enterprise Core
    43, # Storage Server Express Core
    44, # Storage Server Standard Core
    45, # Storage Server Workgroup Core
    29, # Web Server Core
  ].include?(sku)

  false
end
solaris_encaps_lookup(ifname) click to toggle source
# File lib/ohai/plugins/solaris2/network.rb, line 72
def solaris_encaps_lookup(ifname)
  return "Ethernet" if ETHERNET_ENCAPS.include?(ifname)
  return "Ethernet" if ifname.eql?("net")
  return "Loopback" if ifname.eql?("lo")

  "Unknown"
end
sorted_ips(family = "inet") click to toggle source

from interface data create array of hashes with ipaddress, scope, and iface sorted by scope, prefixlen and then ipaddress where longest prefixes first

# File lib/ohai/plugins/network.rb, line 30
def sorted_ips(family = "inet")
  raise "bad family #{family}" unless %w{inet inet6}.include? family

  # priority of ipv6 link scopes to sort by later
  scope_prio = [ "global", "site", "link", "host", "node", nil ]

  # grab ipaddress, scope, and iface for sorting later
  ipaddresses = []
  Mash[network["interfaces"]].each do |iface, iface_v|
    next if iface_v.nil? || !iface_v.key?("addresses")

    iface_v["addresses"].each do |addr, addr_v|
      next if addr_v.nil? || (!addr_v.key? "family") || 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]) || 999999 ),
      128 - v[:ipaddress].prefix.to_i,
      v[:ipaddress].to_i,
    ]
  end
end
standard_array(devices, d_id, tag, line) click to toggle source
# File lib/ohai/plugins/linux/lspci.rb, line 40
def standard_array(devices, d_id, tag, line)
  if !devices[d_id][tag].is_a?(Array)
    devices[d_id][tag] = [line]
  else
    devices[d_id][tag].push(line)
  end
end
standard_form(devices, d_id, hhhh, tag, line) click to toggle source
# File lib/ohai/plugins/linux/lspci.rb, line 34
def standard_form(devices, d_id, hhhh, tag, line)
  tmp = line.scan(/(.*)\s\[(#{hhhh})\]/)[0]
  devices[d_id]["#{tag}_name"] = tmp[0]
  devices[d_id]["#{tag}_id"] = tmp[1]
end
system_profiler(datatype) click to toggle source
# File lib/ohai/plugins/darwin/hardware.rb, line 23
def system_profiler(datatype)
  sp_cmd = "system_profiler #{datatype} -xml"
  # Hardware queries
  sp_std = shell_out(sp_cmd)
  Plist.parse_xml(sp_std.stdout)
end
tcp_ip_dhcp_domain() click to toggle source
# File lib/ohai/plugins/azure.rb, line 75
def tcp_ip_dhcp_domain
  return unless RUBY_PLATFORM.match?(/mswin|mingw32|windows/)

  require "win32/registry" unless defined?(Win32::Registry)

  begin
    key = Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters")
    dhcp_domain = key["DhcpDomain"]
    Ohai::Log.trace("Plugin Azure: DhcpDomain registry value is #{dhcp_domain}")
  rescue Win32::Registry::Error
    Ohai::Log.trace("Plugin Azure: DhcpDomain registry value cannot be found")
  end

  dhcp_domain
end
vboxmanage_exists?() click to toggle source
# File lib/ohai/plugins/darwin/virtualization.rb, line 26
def vboxmanage_exists?
  which("VBoxManage")
end
vboxmanage_list_blocks(query_type, name_key) click to toggle source

query virtualbox for a list of #{query_type} items these queries return a result set that is delimited by multiple successive newlines, with each block containing key/value pairs delimited by a colon (:) and column aligned

the keys of each k/v pair are normalized to lowercase

# File lib/ohai/plugins/virtualbox.rb, line 84
def vboxmanage_list_blocks(query_type, name_key)
  # ignore unrecognized query type
  supported_queries = %w{
    bridgedifs dhcpservers dvds hdds hostdvds
    hostfloppies hostonlyifs natnets
  }
  return nil unless supported_queries.include? query_type

  results = Mash.new

  so_cmd = "VBoxManage list --sorted #{query_type}"
  logger.trace(so_cmd)
  so = shell_out(so_cmd)
  # raise an exception if the command fails
  # so.error!

  if so.exitstatus == 0
    # break the result into paragraph blocks, on successive newlines
    so.stdout.each_line("") do |blk|
      # remove the multiple newlines of each record
      blk.chomp!.chomp!
      # initialize a blank record hash
      record = Mash.new
      # parse the record block into key/value pairs
      blk.each_line do |line|
        next unless line.include? ":"

        # split the line into key/value pair
        key, right = line.split(":", 2)

        # strip the leading/trailing whitespace if the value is not nil
        value = right.nil? ? "" : right.strip
        record[key.downcase] = value
      end

      # insert the record into the list of results
      if record.key? name_key.downcase
        name = record.delete(name_key.downcase)
        results[name] = record
      end
    end
  end
  results
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin VboxHost: Could not run '#{so_cmd}'. Skipping data")
end
vboxmanage_list_vms() click to toggle source

query virtualbox for each configured vm, as well as each guest's individual configuration settings

# File lib/ohai/plugins/virtualbox.rb, line 28
def vboxmanage_list_vms
  vms = Mash.new
  so_cmd = "VBoxManage list --sorted vms"
  logger.trace(so_cmd)
  so = shell_out(so_cmd)

  if so.exitstatus == 0
    # parse the output
    so.stdout.lines.each do |line|
      case line
      when /^"(\S*)" \{(\S*)\}$/
        name = Regexp.last_match(1)
        uuid = Regexp.last_match(2)
        vms[name] = vboxmanage_vminfo(uuid)
      end
    end
  end
  vms
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin VboxHost: Could not run 'VBoxManage list --sorted vms'. Skipping data")
end
vboxmanage_vminfo(machine_id) click to toggle source

query the vminfo for particular guest instance, normalizing the fields so that they're not enclosed in double-quotes (“)

# File lib/ohai/plugins/virtualbox.rb, line 52
def vboxmanage_vminfo(machine_id)
  vm = Mash.new

  so_cmd = "VBoxManage showvminfo #{machine_id} --machinereadable"
  logger.trace(so_cmd)
  so = shell_out(so_cmd)

  if so.exitstatus == 0
    so.stdout.lines.each do |line|
      line.chomp!
      left, right = line.split("=")

      # remove enclosing quotes, if needed
      key = left.delete_prefix('"').delete_suffix('"')

      # skip the name attribute since that is the parent key
      next if key == "name"

      vm[key.downcase] = right.delete_prefix('"').delete_suffix('"')
    end
  end
  vm
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin VboxHost: Could not run '#{so_cmd}'. Skipping data")
end
version_command() click to toggle source
# File lib/ohai/plugins/powershell.rb, line 58
def version_command
  [
    "$progresspreference = 'silentlycontinue'",
    "$PSVersionTable.PSCompatibleVersions | foreach {$_.tostring()}",
  ].join("; ")
end
virtconn() click to toggle source
# File lib/ohai/plugins/libvirt.rb, line 40
def virtconn
  @virt_connect ||= Libvirt.open_read_only("#{emu}:///system")
end
windows_encaps_lookup(encap) click to toggle source
# File lib/ohai/plugins/windows/network.rb, line 24
def windows_encaps_lookup(encap)
  return "Ethernet" if encap.eql?("Ethernet 802.3")

  encap
end
xcode_installed?() click to toggle source
# File lib/ohai/plugins/c.rb, line 35
def xcode_installed?
  logger.trace("Plugin C: Checking for Xcode Command Line Tools.")
  so = shell_out("/usr/bin/xcode-select -p")
  if so.exitstatus == 0
    logger.trace("Plugin C: Xcode Command Line Tools found.")
    true
  else
    logger.trace("Plugin C: Xcode Command Line Tools not found.")
    false
  end
rescue Ohai::Exceptions::Exec
  logger.trace("Plugin C: xcode-select binary could not be found. Skipping data.")
end