class Object
Constants
- MAC_MATCH
- Mash
For historical reasons we inject
Mash
directly into the top level class namespace
Public Instance Methods
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
# 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
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
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
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
# 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
# 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
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
# 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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# File lib/ohai/plugins/solaris2/virtualization.rb, line 28 def collect_solaris_guestid shell_out("/usr/sbin/zoneadm list -p").stdout.split(":").first end
# 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
# 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
# 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
# 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
# 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
# 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
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
# 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
# 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
# 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
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
# 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
# File lib/ohai/plugins/darwin/virtualization.rb, line 42 def docker_exists? which("docker") end
# 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
# 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
# File lib/ohai/plugins/libvirt.rb, line 29 def emu @emu ||= (virtualization[:system].eql?("kvm") ? "qemu" : virtualization[:system]) end
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
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
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
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
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
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
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
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
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
# File lib/ohai/plugins/linux/network.rb, line 42 def ethtool_binary_path @ethtool ||= which("ethtool") end
# File lib/ohai/plugins/darwin/network.rb, line 74 def excluded_setting?(setting) setting.match("_sw_cksum") end
# 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
# 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
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
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
# 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
# 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
# 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
# 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
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
# 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
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
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
@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
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
# 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
# File lib/ohai/plugins/darwin/virtualization.rb, line 38 def fusion_exists? file_exist?("/Applications/VMware\ Fusion.app/") end
# 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
# 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
# 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
# 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
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
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
# 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
# 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
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
# 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
# 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
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 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
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
# 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
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
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
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
# 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
# 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
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 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
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
@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
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 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
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
# 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
# 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
# File lib/ohai/plugins/habitat.rb, line 22 def habitat_binary @habitat_binary ||= which("hab") end
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
# 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
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
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
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
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
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
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
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
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
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
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
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
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
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
# File lib/ohai/plugins/azure.rb, line 71 def has_reddog_dhcp_domain? tcp_ip_dhcp_domain == "reddog.microsoft.com" end
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
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
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
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
# 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
# File lib/ohai/plugins/linux/network.rb, line 554 def interface_address_not_link_level?(iface, address) !(iface[:addresses][address][:scope].casecmp("link") == 0) end
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
# 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
# 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
# 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
# File lib/ohai/plugins/darwin/virtualization.rb, line 34 def ioreg_exists? which("ioreg") end
# File lib/ohai/plugins/linux/network.rb, line 38 def ipv6_enabled? file_exist? "/proc/net/if_inet6" end
# File lib/ohai/plugins/linux/network.rb, line 46 def is_openvz? @openvz ||= file_directory?("/proc/vz") end
# File lib/ohai/plugins/linux/network.rb, line 50 def is_openvz_host? is_openvz? && file_directory?("/proc/bc") end
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
determine link stats, vlans, queue length, and state for an interface using ip
# File lib/ohai/plugins/linux/network.rb, line 349 def link_statistics(iface, net_counters) so = shell_out("ip -d -s link") tmp_int = nil on_rx = true so.stdout.lines do |line| if line =~ IPROUTE_INT_REGEX tmp_int = $2 iface[tmp_int] ||= Mash.new net_counters[tmp_int] ||= Mash.new end if /^\s+(ip6tnl|ipip)/.match?(line) iface[tmp_int][:tunnel_info] = {} words = line.split words.each_with_index do |word, index| case word when "external" iface[tmp_int][:tunnel_info][word] = true when "any", "ipip6", "ip6ip6" iface[tmp_int][:tunnel_info][:proto] = word when "remote", "local", "encaplimit", "hoplimit", "tclass", "flowlabel", "addrgenmode", "numtxqueues", "numrxqueues", "gso_max_size", "gso_max_segs" iface[tmp_int][:tunnel_info][word] = words[index + 1] end end end if line =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ int = on_rx ? :rx : :tx net_counters[tmp_int][int] ||= Mash.new net_counters[tmp_int][int][:bytes] = $1 net_counters[tmp_int][int][:packets] = $2 net_counters[tmp_int][int][:errors] = $3 net_counters[tmp_int][int][:drop] = $4 if int == :rx net_counters[tmp_int][int][:overrun] = $5 else net_counters[tmp_int][int][:carrier] = $5 net_counters[tmp_int][int][:collisions] = $6 end on_rx = !on_rx end if line =~ /qlen (\d+)/ net_counters[tmp_int][:tx] ||= Mash.new net_counters[tmp_int][:tx][:queuelen] = $1 end if line =~ /vlan id (\d+)/ || line =~ /vlan protocol ([\w\.]+) id (\d+)/ if $2 tmp_prot = $1 tmp_id = $2 else tmp_id = $1 end iface[tmp_int][:vlan] ||= Mash.new iface[tmp_int][:vlan][:id] = tmp_id iface[tmp_int][:vlan][:protocol] = tmp_prot if tmp_prot vlan_flags = line.scan(/(REORDER_HDR|GVRP|LOOSE_BINDING)/) if vlan_flags.length > 0 iface[tmp_int][:vlan][:flags] = vlan_flags.flatten.uniq end end # https://rubular.com/r/JRp6lNANmpcLV5 if line =~ /\sstate (\w+)/ iface[tmp_int]["state"] = $1.downcase end end iface end
# 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
# 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
# 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
# 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
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
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
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
# 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
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
# 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
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
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
# File lib/ohai/plugins/linux/virtualization.rb, line 27 def lxc_version_exists? which("lxc-version") || which("lxc-start") end
# 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
# 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
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
# 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
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
# 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
# File lib/ohai/plugins/linux/virtualization.rb, line 31 def nova_exists? which("nova") end
# File lib/ohai/plugins/cloud.rb, line 126 def on_alibaba? alibaba != nil end
# File lib/ohai/plugins/java.rb, line 71 def on_darwin? RUBY_PLATFORM.downcase.include?("darwin") end
# File lib/ohai/plugins/cloud.rb, line 141 def on_gce? gce != nil end
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
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
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
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
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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# File lib/ohai/plugins/linux/network.rb, line 465 def parse_ip_addr_link_line(cint, iface, line) if line =~ %r{link/(\w+) ([\da-f\:]+) } iface[cint][:encapsulation] = linux_encaps_lookup($1) unless $2 == "00:00:00:00:00:00" iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$2.upcase] = { "family" => "lladdr" } end end end
# 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
# 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
# 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
# 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
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
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
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
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
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
# File lib/ohai/plugins/linux/virtualization.rb, line 39 def podman_exists? which("podman") end
# File lib/ohai/plugins/powershell.rb, line 65 def powershell_command ["powershell.exe", "-NoLogo", "-NonInteractive", "-NoProfile", "-Command", ].join(" ") end
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
# File lib/ohai/plugins/darwin/virtualization.rb, line 30 def prlctl_exists? which("prlctl") end
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
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
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
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
# 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
# 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
# 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
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
# 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
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
# 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
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
# 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
# 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
# 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
# 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
# File lib/ohai/plugins/darwin/virtualization.rb, line 26 def vboxmanage_exists? which("VBoxManage") end
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
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
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
# File lib/ohai/plugins/powershell.rb, line 58 def version_command [ "$progresspreference = 'silentlycontinue'", "$PSVersionTable.PSCompatibleVersions | foreach {$_.tostring()}", ].join("; ") end
# File lib/ohai/plugins/libvirt.rb, line 40 def virtconn @virt_connect ||= Libvirt.open_read_only("#{emu}:///system") end
# File lib/ohai/plugins/windows/network.rb, line 24 def windows_encaps_lookup(encap) return "Ethernet" if encap.eql?("Ethernet 802.3") encap end
# 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