class Object
Constants
- ETHERNET_ENCAPS
- IPROUTE_INT_REGEX
Match the lead line for an interface from iproute2 3: eth0 at eth0.11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP The '@eth0:' portion doesn't exist on primary interfaces and thus is optional in the regex
- WINDOWS_ATTRIBUTE_ALIASES
Public Instance Methods
# File lib/ohai/plugins/solaris2/network.rb, line 76 def arpname_to_ifname(iface, arpname) iface.keys.each do |ifn| return ifn if ifn.split(":")[0].eql?(arpname) end nil end
Determines the platform version for F5 Big-IP systems
@returns [String] bigip Linux version from /etc/f5-release
# File lib/ohai/plugins/linux/platform.rb, line 93 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 Ohai::Log.warn("Detected F5 Big-IP, but /etc/f5-release could not be parsed to determine platform_version") nil end
common *bsd code for collecting modules data
# File lib/ohai/plugins/kernel.rb, line 41 def bsd_modules(path) modules = Mash.new so = shell_out("#{Ohai.abs_path(path)}") 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 99 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 111 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 75 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! Ohai::Log.debug("Plugin Network: Parsing #{line}") if 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 Ohai::Log.debug("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] Ohai::Log.debug("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 # 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.has_key?(route_entry[:src]) || addr.values.all? { |a| a["family"] != family[:name] } Ohai::Log.debug("Plugin Network: Skipping route entry whose src does not match the interface IP") next end end iface[route_int][:routes] = Array.new unless iface[route_int][:routes] iface[route_int][:routes] << route_entry end end iface end
returns the default route with the lowest metric (unspecified metric is 0)
# File lib/ohai/plugins/linux/network.rb, line 388 def choose_default_route(routes) routes.select do |r| r[:destination] == "default" end.sort do |x, y| (x[:metric].nil? ? 0 : x[:metric].to_i) <=> (y[:metric].nil? ? 0 : y[:metric].to_i) end.first end
# File lib/ohai/plugins/c.rb, line 23 def collect(cmd, &block) so = shell_out(cmd) if so.exitstatus == 0 yield(so) else Ohai::Log.debug("Plugin C: '#{cmd}' failed. Skipping data.") end rescue Ohai::Exceptions::Exec Ohai::Log.debug("Plugin C: '#{cmd}' binary could not be found. Skipping data.") end
# File lib/ohai/plugins/hostname.rb, line 58 def collect_domain # Domain is everything after the first dot if fqdn fqdn =~ /.+?\.(.*)/ domain $1 end end
# File lib/ohai/plugins/c.rb, line 48 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-debug --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 85 def collect_glibc # glibc ["/lib/libc.so.6", "/lib64/libc.so.6"].each do |glibc| collect( Ohai.abs_path( glibc )) 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 end
# File lib/ohai/plugins/hostname.rb, line 66 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/c.rb, line 152 def collect_hpux_cc # hpux cc collect("what /opt/ansic/bin/cc") do |so| description = so.stdout.split($/).select { |line| line =~ /HP C Compiler/ }.first if description output = description.split @c[:hpcc] = Mash.new @c[:hpcc][:version] = output[1] if output.size >= 1 @c[:hpcc][:description] = description.strip end end end
# File lib/ohai/plugins/packages.rb, line 145 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/aix/filesystem.rb, line 70 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.has_key?(key) end mount_hash.merge(df_hash) end
# File lib/ohai/plugins/joyent.rb, line 36 def collect_pkgsrc data = ::File.read("/opt/local/etc/pkg_install.conf") rescue nil if data /PKG_PATH=(.*)/.match(data)[1] rescue nil end end
# File lib/ohai/plugins/joyent.rb, line 27 def collect_product_file data = ::File.read("/etc/product") rescue nil if data data.strip.split("\n") else [] end end
# File lib/ohai/plugins/packages.rb, line 83 def collect_programs_from_registry_key(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 Win32::Registry::HKEY_LOCAL_MACHINE.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 26 def collect_solaris_guestid command = "/usr/sbin/zoneadm list -p" so = shell_out(command) so.stdout.split(":").first end
# File lib/ohai/plugins/c.rb, line 140 def collect_sunpro # 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 162 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| 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 124 def collect_xlc # ibm xlc so = shell_out("xlc -qversion") if so.exitstatus == 0 || (so.exitstatus >> 8) == 249 description = so.stdout.split($/).first if description =~ /V(\d+\.\d+)/ @c[:xlc] = Mash.new @c[:xlc][:version] = $1 @c[:xlc][:description] = description.strip end end rescue Ohai::Exceptions::Exec Ohai::Log.debug("Plugin C: 'xlc' binary could not be found. Skipping data.") end
# File lib/ohai/plugins/linux/mdadm.rb, line 24 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 38 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 shard_seed Digest::MD5.hexdigest(data)[0...7].to_i(16) end
Determines the platform version for Cumulus Linux systems
@returns [String] cumulus Linux version from /etc/cumulus/etc.replace/os-release
# File lib/ohai/plugins/linux/platform.rb, line 80 def cumulus_version release_contents = File.read("/etc/cumulus/etc.replace/os-release") release_contents.match(/VERSION_ID=(.*)/)[1] rescue NoMethodError, Errno::ENOENT, Errno::EACCES # rescue regex failure, file missing, or permission denied Ohai::Log.warn("Detected Cumulus Linux, but /etc/cumulus/etc/replace/os-release could not be parsed to determine platform_version") nil end
# File lib/ohai/plugins/darwin/network.rb, line 53 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
Determines the platform version for Debian based systems
@returns [String] version of the platform
# File lib/ohai/plugins/linux/platform.rb, line 106 def debian_platform_version if platform == "cumulus" cumulus_version else # not cumulus File.read("/etc/debian_version").chomp end end
# File lib/ohai/plugins/shard.rb, line 32 def default_sources [:machinename, :serial, :uuid] end
Determines the platform_family based on the platform
@returns [String] platform_family value
# File lib/ohai/plugins/linux/platform.rb, line 119 def determine_platform_family case platform when /debian/, /ubuntu/, /linuxmint/, /raspbian/, /cumulus/ # apt-get+dpkg almost certainly goes here "debian" when /oracle/, /centos/, /redhat/, /scientific/, /enterpriseenterprise/, /xenserver/, /cloudlinux/, /ibm_powerkvm/, /parallels/, /nexus_centos/, /clearos/, /bigip/ # 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. "rhel" when /amazon/ "amazon" when /suse/ "suse" when /fedora/, /pidora/, /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 /slackware/ "slackware" when /arch/ "arch" when /exherbo/ "exherbo" when /alpine/ "alpine" when /clearlinux/ "clearlinux" end end
# File lib/ohai/plugins/ip_scopes.rb, line 64 def docker_iface?(interface) interface["type"] == "docker" end
determine layer 1 details for the interface using ethtool
# File lib/ohai/plugins/linux/network.rb, line 150 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! Ohai::Log.debug("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 ring parameters for the interface using ethtool
# File lib/ohai/plugins/linux/network.rb, line 174 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}") Ohai::Log.debug("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 line =~ /Pre-set maximums/ type = "max" next end if line =~ /Current hardware settings/ 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 40 def ethtool_binary_path @ethtool ||= which("ethtool") end
# File lib/ohai/plugins/darwin/network.rb, line 69 def excluded_setting?(setting) setting.match("_sw_cksum") end
# File lib/ohai/plugins/ssh_host_key.rb, line 23 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 52 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 Ohai::Log.warn("neighbor list has entries for unknown interface #{interface}") next end interface[neigh_attr] = Mash.new unless interface[neigh_attr] 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 427 def favored_default_route(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.sort_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.first end
# File lib/ohai/plugins/azure.rb, line 82 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/ec2.rb, line 100 def file_val_if_exists(path) if ::File.exist?(path) ::File.read(path) end end
# File lib/ohai/plugins/linux/filesystem.rb, line 25 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 63 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::NetworkConstants::FAMILIES[family] + "_interface" gw_attr = Ohai::Mixin::NetworkConstants::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? Ohai::Log.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] } # link level default route Ohai::Log.debug("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.select do |v| network_contains_address(network[gw_attr], v[:ipaddress], v[:iface]) end.first if r.nil? r = gw_if_ips.first Ohai::Log.debug("Plugin Network: [#{family}] no ipaddress/mask on #{network[int_attr]} matching the gateway #{network[gw_attr]}, picking #{r[:ipaddress]}") else Ohai::Log.debug("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 Ohai::Log.debug("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 114 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
# File lib/ohai/plugins/passwd.rb, line 6 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 42 def from_cmd(cmd) so = shell_out(cmd) so.stdout.split($/)[0] end
# File lib/ohai/plugins/solaris2/network.rb, line 84 def full_interface_name(iface, part_name, index) iface.each do |name, attrs| next unless attrs && attrs.respond_to?(:[]) return name if /^#{part_name}($|:)/.match(name) && attrs[:index] == index end nil end
# File lib/ohai/plugins/darwin/virtualization.rb, line 36 def fusion_exists? ::File.exist?("/Applications/VMware\ Fusion.app/") end
# File lib/ohai/plugins/zpools.rb, line 29 def gather_pool_info pools = Mash.new # 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 pools end
# File lib/ohai/plugins/darwin/filesystem.rb, line 25 def generate_device_view(fs) view = {} fs.each_value do |entry| view[entry[:device]] = Mash.new unless view[entry[:device]] entry.each do |key, val| next if %w{device mount}.include?(key) view[entry[:device]][key] = val end if entry[:mount] view[entry[:device]][:mounts] = [] unless view[entry[:device]][:mounts] view[entry[:device]][:mounts] << entry[:mount] end end view end
# File lib/ohai/plugins/darwin/filesystem.rb, line 41 def generate_mountpoint_view(fs) view = {} fs.each_value do |entry| next unless entry[:mount] view[entry[:mount]] = Mash.new unless view[entry[:mount]] entry.each do |key, val| next if %w{mount device}.include?(key) view[entry[:mount]][key] = val end if entry[:device] view[entry[:mount]][:devices] = [] unless view[entry[:mount]][:devices] view[entry[:mount]][:devices] << entry[:device] end end view end
Fill cloud hash with azure values
# File lib/ohai/plugins/cloud.rb, line 267 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 290 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 24 def get_dmi_property(dmi, thing) %w{system base_board chassis}.each do |section| unless dmi[section][thing].strip.empty? return dmi[section][thing] end end end
Fill cloud hash with ec2 values
# File lib/ohai/plugins/cloud.rb, line 156 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 223 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 125 def get_gce_values public_ips = gce["instance"]["networkInterfaces"].collect do |interface| if interface.has_key?("accessConfigs") interface["accessConfigs"].collect { |ac| ac["externalIp"] unless ac["externalIp"] == "" } end end.flatten.compact private_ips = gce["instance"]["networkInterfaces"].collect do |interface| interface["ip"] end.compact 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 88 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 114 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 Ohai::Log.debug("Plugin Rackspace: Unable to find xenstore-read, cannot capture instance ID information for Rackspace cloud") nil end
Names linode ip address
name - symbol of ohai name (e.g. :public_ip) eth - Interface name (e.g. :eth0)
Alters linode mash with new interface based on name parameter
# File lib/ohai/plugins/linode.rb, line 45 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 23 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 Ohai::Log.debug('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 202 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 32 def get_mac_address(addresses) detected_addresses = addresses.detect { |address, keypair| keypair == { "family" => "lladdr" } } if detected_addresses return detected_addresses.first else return "" 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 383 def get_mac_for_interface(interfaces, interface) interfaces[interface][:addresses].select { |k, v| v["family"] == "lladdr" }.first.first unless interfaces[interface][:addresses].nil? || interfaces[interface][:flags].include?("NOARP") end
Fill cloud hash with openstack values
# File lib/ohai/plugins/cloud.rb, line 245 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 126 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 Ohai::Log.debug("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 Ohai::Log.debug("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 178 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
# File lib/ohai/plugins/linux/platform.rb, line 23 def get_redhatish_platform(contents) contents[/^Red Hat/i] ? "redhat" : contents[/(\w+)/i, 1].downcase end
# File lib/ohai/plugins/linux/platform.rb, line 27 def get_redhatish_version(contents) contents[/Rawhide/i] ? contents[/((\d+) \(Rawhide\))/i, 1].downcase : contents[/release ([\d\.]+)/, 1] end
Get the rackspace region
# File lib/ohai/plugins/rackspace.rb, line 100 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 line =~ /^region/ end end rescue Ohai::Exceptions::Exec Ohai::Log.debug("Plugin Rackspace: Unable to find xenstore-ls, cannot capture region information for Rackspace cloud") nil end
# File lib/ohai/plugins/vmware.rb, line 43 def get_vm_attributes(vmtools_path) if !File.exist?(vmtools_path) Ohai::Log.debug("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 vmware[param] =~ /UpdateInfo failed/ vmware[param] = nil end end # vmware-toolbox-cmd <param> status commands # Iterate through each parameter supported by the "vwware-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 Ohai::Log.debug("Plugin VMware: Error while collecting VMware guest attributes") end end end
# File lib/ohai/plugins/azure.rb, line 56 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 line =~ /unknown-245/ Ohai::Log.debug("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 30 def has_do_dmi? begin # detect a vendor of "DigitalOcean" if dmi[:bios][:all_records][0][:Vendor] == "DigitalOcean" Ohai::Log.debug("Plugin DigitalOcean: has_do_dmi? == true") return true end rescue NoMethodError # dmi[:bios][:all_records][0][:Vendor] may not exist end Ohai::Log.debug("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 file_val_if_exists("/sys/class/dmi/id/bios_vendor") =~ /Amazon/ Ohai::Log.debug("Plugin EC2: has_ec2_amazon_dmi? == true") true else Ohai::Log.debug("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 =~ /mswin|mingw32|windows/ require "wmi-lite/wmi" wmi = WmiLite::Wmi.new if wmi.first_of("Win32_ComputerSystemProduct")["identifyingnumber"] =~ /^ec2/ Ohai::Log.debug("Plugin EC2: has_ec2_identifying_number? == true") return true end else Ohai::Log.debug("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 file_val_if_exists("/sys/class/dmi/id/bios_version") =~ /amazon/ Ohai::Log.debug("Plugin EC2: has_ec2_xen_dmi? == true") true else Ohai::Log.debug("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 file_val_if_exists("/sys/hypervisor/uuid") =~ /^ec2/ Ohai::Log.debug("Plugin EC2: has_ec2_xen_uuid? == true") return true end Ohai::Log.debug("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 42 def has_euca_mac? network[:interfaces].values.each do |iface| mac = get_mac_address(iface[:addresses]) if mac =~ /^[dD]0:0[dD]:/ Ohai::Log.debug("Plugin Eucalyptus: has_euca_mac? == true (#{mac})") return true end end Ohai::Log.debug("Plugin Eucalyptus: has_euca_mac? == false") false end
Checks for matching linode kernel name
Returns true or false
# File lib/ohai/plugins/linode.rb, line 26 def has_linode_kernel? if kernel_data = kernel kernel_data[:release].split("-").last =~ /linode/ end 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 =~ /mswin|mingw32|windows/ require "wmi-lite/wmi" wmi = WmiLite::Wmi.new if wmi.first_of("Win32_ComputerSystem")["PrimaryOwnerName"] == "Rackspace" Ohai::Log.debug("Plugin Rackspace: has_rackspace_manufacturer? == true") return 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 64 def has_real_java? return true unless on_darwin? shell_out("/usr/libexec/java_home").status.success? 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 49 def has_waagent? if File.exist?("/usr/sbin/waagent") || Dir.exist?('C:\WindowsAzure') Ohai::Log.debug("Plugin Azure: Found waagent used by Azure.") true end end
Helpers
# File lib/ohai/plugins/aix/network.rb, line 27 def hex_to_dec_netmask(netmask) # example '0xffff0000' -> '255.255.0.0' dec = netmask[2..3].to_i(16).to_s(10) [4, 6, 8].each { |n| dec = dec + "." + netmask[n..n + 1].to_i(16).to_s(10) } dec end
common initial kernel attribute values
# File lib/ohai/plugins/kernel.rb, line 29 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.split($/)[0] end kernel end
create the basic structure we'll store our data in
# File lib/ohai/plugins/azure.rb, line 71 def initialize_metadata_mash metadata = Mash.new metadata["compute"] = Mash.new 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 406 def interface_address_not_link_level?(iface, address) !(iface[:addresses][address][:scope].casecmp("link") == 0) end
# File lib/ohai/plugins/linux/network.rb, line 396 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 401 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 410 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 32 def ioreg_exists? which("ioreg") end
# File lib/ohai/plugins/linux/network.rb, line 36 def ipv6_enabled? File.exist? "/proc/net/if_inet6" end
# File lib/ohai/plugins/linux/network.rb, line 44 def is_openvz? @openvz ||= ::File.directory?("/proc/vz") end
# File lib/ohai/plugins/linux/network.rb, line 48 def is_openvz_host? is_openvz? && ::File.directory?("/proc/bc") end
# File lib/ohai/plugins/joyent.rb, line 43 def is_smartos? platform == "smartos" end
determine link stats, vlans, queue length, and state for an interface using ip
# File lib/ohai/plugins/linux/network.rb, line 204 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 unless iface[tmp_int] net_counters[tmp_int] = Mash.new unless net_counters[tmp_int] end if line =~ /^\s+(ip6tnl|ipip)/ 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 unless net_counters[tmp_int][int] 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 unless net_counters[tmp_int][:tx] 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 unless iface[tmp_int][:vlan] 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 if line =~ /state (\w+)/ iface[tmp_int]["state"] = $1.downcase end end iface end
# File lib/ohai/plugins/linux/network.rb, line 25 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/darwin/network.rb, line 73 def locate_interface(ifaces, ifname, mac) return ifname unless ifaces[ifname].nil? # oh well, time to go hunting! return ifname.chop if ifname =~ /\*$/ ifaces.keys.each do |ifc| ifaces[ifc][:addresses].keys.each do |addr| return ifc if addr.eql? mac end end nil end
# File lib/ohai/plugins/digital_ocean.rb, line 44 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 55 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
Returns true or false
# File lib/ohai/plugins/linode.rb, line 35 def looks_like_linode? hint?("linode") || has_linode_kernel? end
# File lib/ohai/plugins/linux/virtualization.rb, line 24 def lxc_version_exists? which("lxc-version") || which("lxc-start") end
# File lib/ohai/plugins/windows/network.rb, line 28 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
windows
# File lib/ohai/plugins/kernel.rb, line 54 def machine_lookup(sys_type) return "i386" if sys_type.eql?("X86-based PC") return "x86_64" if sys_type.eql?("x64-based PC") sys_type end
# File lib/ohai/plugins/linux/network.rb, line 286 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
# File lib/ohai/plugins/windows/network.rb, line 48 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 122 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 33 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 anothe roperating 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 28 def nova_exists? which("nova") end
# File lib/ohai/plugins/java.rb, line 69 def on_darwin? RUBY_PLATFORM.downcase.include?("darwin") end
# File lib/ohai/plugins/cloud.rb, line 121 def on_gce? gce != nil end
do we have the openstack dmi data
# File lib/ohai/plugins/openstack.rb, line 30 def openstack_dmi? # detect a manufacturer of OpenStack Foundation if get_attribute(:dmi, :system, :all_records, 0, :Manufacturer) =~ /OpenStack/ Ohai::Log.debug("Plugin Openstack: has_openstack_dmi? == true") true else Ohai::Log.debug("Plugin Openstack: has_openstack_dmi? == false") false end end
check for the ohai hint and log debug messaging
# File lib/ohai/plugins/openstack.rb, line 42 def openstack_hint? if hint?("openstack") Ohai::Log.debug("Plugin Openstack: openstack hint present") true else Ohai::Log.debug("Plugin Openstack: openstack hint not present") false end end
dreamhost systems have the dhc-user on them
# File lib/ohai/plugins/openstack.rb, line 53 def openstack_provider return "dreamhost" if get_attribute("etc", "passwd", "dhc-user") "openstack" end
windows
# File lib/ohai/plugins/kernel.rb, line 61 def os_lookup(sys_type) return "Unknown" if sys_type.to_s.eql?("0") return "Other" if sys_type.to_s.eql?("1") return "MSDOS" if sys_type.to_s.eql?("14") return "WIN3x" if sys_type.to_s.eql?("15") return "WIN95" if sys_type.to_s.eql?("16") return "WIN98" if sys_type.to_s.eql?("17") return "WINNT" if sys_type.to_s.eql?("18") return "WINCE" if sys_type.to_s.eql?("19") nil 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 71 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 54 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
# 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/aix/filesystem.rb, line 25 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" key = "#{$1}:#{$6}" else key = $1 end 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] = $6 # an entry starting with 'G' or / (E.G. /tmp or /var) when /^\s*(G.*?|\/\w)/ if fields[0] == "Global" key = fields[0] + ":" + fields[1] else key = fields[0] end oldie[key] ||= Mash.new oldie[key][:mount] = fields[1] oldie[key][:fs_type] = fields[2] oldie[key][:mount_options] = fields[6].split(",") # entries occupying the 'Node' column parsed here else key = fields[0] + ":" + fields[1] oldie[key] ||= Mash.new oldie[key][:mount] = fields[1] 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 307 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 366 def parse_ip_addr_inet6_line(cint, iface, line) if line =~ /inet6 ([a-f0-9\:]+)\/(\d+) scope (\w+)( .*)?/ iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] 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 329 def parse_ip_addr_inet_line(cint, iface, line) if line =~ /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 unless iface[cint] # Create the fake alias interface if needed iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] 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 319 def parse_ip_addr_link_line(cint, iface, line) if line =~ /link\/(\w+) ([\da-f\:]+) / iface[cint][:encapsulation] = linux_encaps_lookup($1) unless $2 == "00:00:00:00:00:00" iface[cint][:addresses] = Mash.new unless iface[cint][:addresses] iface[cint][:addresses][$2.upcase] = { "family" => "lladdr" } end end end
# File lib/ohai/plugins/linux/filesystem.rb, line 33 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/darwin/network.rb, line 23 def parse_media(media_string) media = Hash.new 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]] = Hash.new unless media.has_key?(line_array[i]) if media[line_array[i]].has_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 else if line_array[i].eql?("autoselect") media["autoselect"] = Hash.new unless media.has_key?("autoselect") media["autoselect"]["options"] = [] end end else media["none"] = { "options" => [] } end end media end
# File lib/ohai/plugins/azure.rb, line 91 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 # blindly add everything in compute to our data structure endpoint_data["compute"].each do |k, v| metadata["compute"][k] = v end # 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 metadata end
using a temporary var to hold routes and their interface name
# File lib/ohai/plugins/linux/network.rb, line 139 def parse_routes(family, iface) iface.collect do |i, iv| if iv[:routes] iv[:routes].collect do |r| r.merge(:dev => i) if r[:family] == family[:name] end.compact end end.compact.flatten end
# File lib/ohai/plugins/powershell.rb, line 65 def powershell_command ["powershell.exe", "-NoLogo", "-NonInteractive", "-NoProfile", "-Command", ].join(" ") end
# File lib/ohai/plugins/ip_scopes.rb, line 56 def ppp_iface?(interface) interface["type"] == "ppp" end
# File lib/ohai/plugins/ip_scopes.rb, line 52 def private_addr?(address) address.to_ip.scope =~ /PRIVATE/ end
# File lib/ohai/plugins/darwin/virtualization.rb, line 28 def prlctl_exists? which("prlctl") 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 38 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) this is ipv6-safe, works on ruby 1.8.7+
# File lib/ohai/plugins/hostname.rb, line 49 def resolve_fqdn hostname = from_cmd("hostname") addrinfo = Socket.getaddrinfo(hostname, nil).first iaddr = IPAddr.new(addrinfo[3]) Socket.gethostbyaddr(iaddr.hton)[0] rescue nil end
# File lib/ohai/plugins/linux/network.rb, line 416 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" # the default route has a gateway and the route matches the gateway !default_route[:via].nil? && IPAddress(route[:destination]).include?(IPAddress(default_route[:via])) end
# File lib/ohai/plugins/ruby.rb, line 23 def run_ruby(command) cmd = "ruby -e \"require 'rbconfig'; #{command}\"" so = shell_out(cmd) so.stdout.strip 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 25 def sanitize_value(value) value == "-" ? nil : value end
# File lib/ohai/plugins/darwin/network.rb, line 62 def scope_lookup(scope) return "Node" if scope.eql?("::1") return "Link" if scope =~ /^fe80\:/ return "Site" if scope =~ /^fec0\:/ "Global" end
# File lib/ohai/plugins/solaris2/network.rb, line 69 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.has_key?("addresses") iface_v["addresses"].each do |addr, addr_v| next if addr_v.nil? || (not addr_v.has_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, ( family == "inet" ? v[:ipaddress].to_u32 : v[:ipaddress].to_u128 ), ] end end
# File lib/ohai/plugins/linux/lspci.rb, line 40 def standard_array(devices, d_id, tag, line) if !devices[d_id][tag].kind_of?(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 22 def system_profiler(datatype) sp_cmd = "system_profiler #{datatype} -xml" # Hardware queries sp_std = shell_out(sp_cmd) sp_hash = Plist.parse_xml(sp_std.stdout) end
# File lib/ohai/plugins/ip_scopes.rb, line 60 def tunnel_iface?(interface) interface["type"] == "tunl" end
# File lib/ohai/plugins/darwin/virtualization.rb, line 24 def vboxmanage_exists? which("VBoxManage") end
# File lib/ohai/plugins/powershell.rb, line 58 def version_command [ "$progresspreference = 'silentlycontinue'", "$PSVersionTable.PSCompatibleVersions | foreach {$_.tostring()}", ].join("; ") end
# File lib/ohai/plugins/windows/network.rb, line 23 def windows_encaps_lookup(encap) return "Ethernet" if encap.eql?("Ethernet 802.3") encap end
# File lib/ohai/plugins/c.rb, line 34 def xcode_installed? Ohai::Log.debug("Plugin C: Checking for Xcode Command Line Tools.") so = shell_out("/usr/bin/xcode-select -p") if so.exitstatus == 0 Ohai::Log.debug("Plugin C: Xcode Command Line Tools found.") return true else Ohai::Log.debug("Plugin C: Xcode Command Line Tools not found.") return false end rescue Ohai::Exceptions::Exec Ohai::Log.debug("Plugin C: xcode-select binary could not be found. Skipping data.") end