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



170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/facter/util/virtual.rb', line 170

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



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



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



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 http://stackoverflow.com/questions/20010199/determining-if-a-process-runs-inside-lxc-docker



153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/facter/util/virtual.rb', line 153

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



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



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 This method is intended to provide an easy seam to mock.



196
197
198
199
200
201
202
203
# File 'lib/facter/util/virtual.rb', line 196

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



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 https://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



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



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



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



183
184
185
# File 'lib/facter/util/virtual.rb', line 183

def self.zlinux?
  "zlinux"
end

.zone?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