module Facter::Util::Virtual

Public Class Methods

docker?() click to toggle source

docker? returns true if the process is running inside of a docker container. Implementation derived from observation of a boot2docker system

# File lib/facter/util/virtual.rb, line 178
def self.docker?
  path = Pathname.new('/proc/1/cgroup')
  return false unless path.readable?
  begin
    in_docker = path.readlines.any? {|l| l.split(":")[2].to_s.start_with? '/docker/' }
  rescue Errno::EPERM => exc
    # This can fail under OpenVZ, just like in .lxc?
    return false
  end
  return true if in_docker
  return false
end
gce?() click to toggle source
# File lib/facter/util/virtual.rb, line 141
def self.gce?
  File.read("/sys/devices/virtual/dmi/id/product_name") =~ /Google/ rescue false
end
hpvm?() click to toggle source
# File lib/facter/util/virtual.rb, line 153
def self.hpvm?
  Facter::Core::Execution.exec("/usr/bin/getconf MACHINE_MODEL").chomp =~ /Virtual Machine/
end
jail?() click to toggle source
# File lib/facter/util/virtual.rb, line 145
def self.jail?
  path = case Facter.value(:kernel)
    when "FreeBSD" then "/sbin"
    when "GNU/kFreeBSD" then "/bin"
  end
  Facter::Core::Execution.exec("#{path}/sysctl -n security.jail.jailed") == "1"
end
kvm?() click to toggle source
# File lib/facter/util/virtual.rb, line 109
def self.kvm?
   txt = if FileTest.exists?("/proc/cpuinfo")
     File.read("/proc/cpuinfo")
   elsif ["FreeBSD", "OpenBSD"].include? Facter.value(:kernel)
     Facter::Util::POSIX.sysctl("hw.model")
   elsif Facter.value(:kernel) == "SunOS" and FileTest.exists?("/usr/sbin/prtconf")
     Facter::Core::Execution.exec("/usr/sbin/prtconf -v")
   end
   (txt =~ /QEMU Virtual (CPU|Machine)/i) ? true : false
end
kvm_type() click to toggle source
# File lib/facter/util/virtual.rb, line 124
def self.kvm_type
  # TODO Tell the difference between kvm and qemu
  # Can't work out a way to do this at the moment that doesn't
  # require a special binary
  if self.kvm?
    "kvm"
  end
end
lspci(command = nil) click to toggle source

lspci is a delegating helper method intended to make it easier to stub the system call without affecting other calls to Facter::Core::Execution#exec

# File lib/facter/util/virtual.rb, line 40
def self.lspci(command = nil)
  if command.nil?
    if ["FreeBSD", "OpenBSD"].include? Facter.value(:kernel)
      command = "pciconf -lv 2>/dev/null"
    else
      command = "lspci 2>/dev/null"
    end
  end

  Facter::Core::Execution.exec command
end
lxc?() click to toggle source

lxc? returns true if the process is running inside of a linux container. Implementation derived from stackoverflow.com/questions/20010199/determining-if-a-process-runs-inside-lxc-docker

# File lib/facter/util/virtual.rb, line 161
def self.lxc?
  path = Pathname.new('/proc/1/cgroup')
  return false unless path.readable?
  begin
    in_lxc = path.readlines.any? {|l| l.split(":")[2].to_s.start_with? '/lxc/' }
  rescue Errno::EPERM => exc
    # If we get "operation not permitted" here, it probably means we are
    # running OpenVZ. We are not running LXC anyway, so...
    return false
  end
  return true if in_lxc
  return false
end
openvz?() click to toggle source
# File lib/facter/util/virtual.rb, line 52
def self.openvz?
  FileTest.directory?("/proc/vz") and not self.openvz_cloudlinux?
end
openvz_cloudlinux?() click to toggle source

Cloudlinux uses OpenVZ to a degree, but always has an empty /proc/vz/ and has /proc/lve/list present

# File lib/facter/util/virtual.rb, line 71
def self.openvz_cloudlinux?
  FileTest.file?("/proc/lve/list") or Dir.glob('/proc/vz/*').empty?
end
openvz_type() click to toggle source

So one can either have #6728 work on OpenVZ or Cloudlinux. Whoo.

# File lib/facter/util/virtual.rb, line 57
def self.openvz_type
  return false unless self.openvz?
  return false unless FileTest.exists?( '/proc/self/status' )

  envid = Facter::Core::Execution.exec( 'grep "envID" /proc/self/status' )
  if envid =~ /^envID:\s+0$/i
  return 'openvzhn'
  elsif envid =~ /^envID:\s+(\d+)$/i
  return 'openvzve'
  end
end
ovirt?() click to toggle source
# File lib/facter/util/virtual.rb, line 137
def self.ovirt?
  File.read("/sys/devices/virtual/dmi/id/product_name") =~ /oVirt Node/ rescue false
end
read_sysfs_dmi_entries(path="/sys/firmware/dmi/entries/1-0/raw") click to toggle source

read_sysfs Reads the raw data as per the documentation at [Detecting if You Are Running in Google Compute Engine](developers.google.com/compute/docs/instances#dmi) This method is intended to provide an easy seam to mock.

@api public

@return [String] or nil if the path does not exist or is unreadable

# File lib/facter/util/virtual.rb, line 204
def self.read_sysfs_dmi_entries(path="/sys/firmware/dmi/entries/1-0/raw")
  if File.readable?(path)
    begin
      Facter::Util::FileRead.read_binary(path)
    rescue Errno::EINVAL
    end
  end
end
rhev?() click to toggle source
# File lib/facter/util/virtual.rb, line 133
def self.rhev?
  File.read("/sys/devices/virtual/dmi/id/product_name") =~ /RHEV Hypervisor/ rescue false
end
virt_what(cmd = "virt-what") click to toggle source

::virt_what is a delegating helper method intended to make it easier to stub the system call without affecting other calls to Facter::Core::Execution#exec

Per bugzilla.redhat.com/show_bug.cgi?id=719611 when run as a non-root user the virt-what command may emit an error message on stdout, and later versions of virt-what may emit this message on stderr. This method ensures stderr is redirected and that error messages are stripped from stdout.

# File lib/facter/util/virtual.rb, line 16
def self.virt_what(cmd = "virt-what")
  if bindir = Facter::Util::Config.override_binary_dir
    command = Facter::Core::Execution.which(File.join(bindir, cmd))
  else
    command = nil
  end

  if !command
    command = Facter::Core::Execution.which(cmd)
    return unless command
  end

  if Facter.value(:kernel) == 'windows'
    redirected_cmd = "#{command} 2>NUL"
  else
    redirected_cmd = "#{command} 2>/dev/null"
  end
  output = Facter::Core::Execution.exec redirected_cmd
  output.gsub(/^virt-what: .*$/, '') if output
end
virtualbox?() click to toggle source
# File lib/facter/util/virtual.rb, line 120
def self.virtualbox?
  File.read("/sys/devices/virtual/dmi/id/product_name") =~ /VirtualBox/ rescue false
end
vserver?() click to toggle source
# File lib/facter/util/virtual.rb, line 82
def self.vserver?
  return false unless FileTest.exists?("/proc/self/status")
  txt = File.open("/proc/self/status", "rb").read
  if txt.respond_to?(:encode!)
    txt.encode!('UTF-16', 'UTF-8', :invalid => :replace)
    txt.encode!('UTF-8', 'UTF-16')
  end
  return true if txt =~ /^(s_context|VxID):[[:blank:]]*[0-9]/
  return false
end
vserver_type() click to toggle source
# File lib/facter/util/virtual.rb, line 93
def self.vserver_type
  if self.vserver?
    if FileTest.exists?("/proc/virtual")
      "vserver_host"
    else
      "vserver"
    end
  end
end
xen?() click to toggle source
# File lib/facter/util/virtual.rb, line 103
def self.xen?
  ["/proc/sys/xen", "/sys/bus/xen", "/proc/xen" ].detect do |f|
    FileTest.exists?(f)
  end
end
zlinux?() click to toggle source
# File lib/facter/util/virtual.rb, line 191
def self.zlinux?
  "zlinux"
end
zone?() click to toggle source
# File lib/facter/util/virtual.rb, line 75
def self.zone?
  return true if FileTest.directory?("/.SUNWnative")
  z = Facter::Core::Execution.exec("/sbin/zonename")
  return false unless z
  return z.chomp != 'global'
end