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)


178
179
180
181
182
183
184
185
186
187
188
189
# 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.include? '/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?Boolean

Returns:

  • (Boolean)


141
142
143
# 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?Boolean

Returns:

  • (Boolean)


153
154
155
# 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?Boolean

Returns:

  • (Boolean)


145
146
147
148
149
150
151
# 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?Boolean

Returns:

  • (Boolean)


109
110
111
112
113
114
115
116
117
118
# 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_typeObject



124
125
126
127
128
129
130
131
# 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) ⇒ 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



40
41
42
43
44
45
46
47
48
49
50
# 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?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)


161
162
163
164
165
166
167
168
169
170
171
172
173
# 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.include? '/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?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/facter/util/virtual.rb', line 52

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)


71
72
73
# 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_typeObject

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



57
58
59
60
61
62
63
64
65
66
67
# 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?Boolean

Returns:

  • (Boolean)


137
138
139
# 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") ⇒ 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



204
205
206
207
208
209
210
211
# 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?Boolean

Returns:

  • (Boolean)


133
134
135
# 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") ⇒ 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
28
29
30
31
32
33
34
35
# 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?Boolean

Returns:

  • (Boolean)


120
121
122
# 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?Boolean

Returns:

  • (Boolean)


82
83
84
85
86
87
88
89
90
91
# 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_typeObject



93
94
95
96
97
98
99
100
101
# 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?Boolean

Returns:

  • (Boolean)


103
104
105
106
107
# 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?Boolean

Returns:

  • (Boolean)


191
192
193
# File 'lib/facter/util/virtual.rb', line 191

def self.zlinux?
  "zlinux"
end

.zone?Boolean

Returns:

  • (Boolean)


75
76
77
78
79
80
# 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