Module: Facter::Util::Virtual

Defined in:
lib/facter/util/virtual.rb

Class Method Summary collapse

Class Method Details

.docker?Boolean

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

Returns:

  • (Boolean)


164
165
166
167
168
169
170
# File 'lib/facter/util/virtual.rb', line 164

def self.docker?
  path = Pathname.new('/proc/1/cgroup')
  return false unless path.readable?
  in_docker = path.readlines.any? {|l| l.split(":")[2].to_s.start_with? '/docker/' }
  return true if in_docker
  return false
end

.gce?Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/facter/util/virtual.rb', line 133

def self.gce?
  File.read("/sys/devices/virtual/dmi/id/product_name") =~ /Google/ rescue false
end

.hpvm?Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/facter/util/virtual.rb', line 145

def self.hpvm?
  Facter::Core::Execution.exec("/usr/bin/getconf MACHINE_MODEL").chomp =~ /Virtual Machine/
end

.jail?Boolean

Returns:

  • (Boolean)


137
138
139
140
141
142
143
# File 'lib/facter/util/virtual.rb', line 137

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?Boolean

Returns:

  • (Boolean)


101
102
103
104
105
106
107
108
109
110
# File 'lib/facter/util/virtual.rb', line 101

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_typeObject



116
117
118
119
120
121
122
123
# File 'lib/facter/util/virtual.rb', line 116

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

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



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/facter/util/virtual.rb', line 32

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?Boolean

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

Returns:

  • (Boolean)


153
154
155
156
157
158
159
# File 'lib/facter/util/virtual.rb', line 153

def self.lxc?
  path = Pathname.new('/proc/1/cgroup')
  return false unless path.readable?
  in_lxc = path.readlines.any? {|l| l.split(":")[2].to_s.start_with? '/lxc/' }
  return true if in_lxc
  return false
end

.openvz?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/facter/util/virtual.rb', line 44

def self.openvz?
  FileTest.directory?("/proc/vz") and not self.openvz_cloudlinux?
end

.openvz_cloudlinux?Boolean

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

Returns:

  • (Boolean)


63
64
65
# File 'lib/facter/util/virtual.rb', line 63

def self.openvz_cloudlinux?
  FileTest.file?("/proc/lve/list") or Dir.glob('/proc/vz/*').empty?
end

.openvz_typeObject

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



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/facter/util/virtual.rb', line 49

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?Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/facter/util/virtual.rb', line 129

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") ⇒ String

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.

Returns:

  • (String)

    or nil if the path does not exist or is unreadable



185
186
187
188
189
190
191
192
# File 'lib/facter/util/virtual.rb', line 185

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?Boolean

Returns:

  • (Boolean)


125
126
127
# File 'lib/facter/util/virtual.rb', line 125

def self.rhev?
  File.read("/sys/devices/virtual/dmi/id/product_name") =~ /RHEV Hypervisor/ rescue false
end

.virt_what(command = "virt-what") ⇒ Object

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.



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/facter/util/virtual.rb', line 16

def self.virt_what(command = "virt-what")
  command = Facter::Core::Execution.which(command)
  return unless command

  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?Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/facter/util/virtual.rb', line 112

def self.virtualbox?
  File.read("/sys/devices/virtual/dmi/id/product_name") =~ /VirtualBox/ rescue false
end

.vserver?Boolean

Returns:

  • (Boolean)


74
75
76
77
78
79
80
81
82
83
# File 'lib/facter/util/virtual.rb', line 74

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_typeObject



85
86
87
88
89
90
91
92
93
# File 'lib/facter/util/virtual.rb', line 85

def self.vserver_type
  if self.vserver?
    if FileTest.exists?("/proc/virtual")
      "vserver_host"
    else
      "vserver"
    end
  end
end

.xen?Boolean

Returns:

  • (Boolean)


95
96
97
98
99
# File 'lib/facter/util/virtual.rb', line 95

def self.xen?
  ["/proc/sys/xen", "/sys/bus/xen", "/proc/xen" ].detect do |f|
    FileTest.exists?(f)
  end
end

.zlinux?Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/facter/util/virtual.rb', line 172

def self.zlinux?
  "zlinux"
end

.zone?Boolean

Returns:

  • (Boolean)


67
68
69
70
71
72
# File 'lib/facter/util/virtual.rb', line 67

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