summaryrefslogtreecommitdiffstats
path: root/lib/facter/virtual.rb
blob: 7c649ba891ffe14902517eee9468e6090de27f82 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# Fact: virtual
#
# Purpose: Determine if the system's hardware is real or virtualised.
#
# Resolution:
#   Assumes physical unless proven otherwise.
#
#   On Darwin, use the macosx util module to acquire the SPDisplaysDataType,
#   from that parse it to see if it's VMWare or Parallels pretending to be the
#   display.
#
#   On Linux, BSD, Solaris and HPUX:
#     Much of the logic here is obscured behind util/virtual.rb, which rather
#     than document here, which would encourage drift, just refer to it.
#   The Xen tests in here rely on /sys and /proc, and check for the presence and
#   contents of files in there.
#   If after all the other tests, it's still seen as physical, then it tries to
#   parse the output of the "lspci", "dmidecode" and "prtdiag" and parses them
#   for obvious signs of being under VMWare or Parallels.
#   Finally it checks for the existence of vmware-vmx, which would hint it's
#   VMWare.
#
# Caveats:
#   Virtualbox detection isn't implemented. 
#   Many checks rely purely on existence of files.
#

require 'facter/util/virtual'

Facter.add("virtual") do
    confine :kernel => "Darwin"

    setcode do
        require 'facter/util/macosx'
        result = "physical"
        output = Facter::Util::Macosx.profiler_data("SPDisplaysDataType")
        if output.is_a?(Hash)
            result = "parallels" if output["spdisplays_vendor-id"] =~ /0x1ab8/
            result = "parallels" if output["spdisplays_vendor"] =~ /[Pp]arallels/
            result = "vmware" if output["spdisplays_vendor-id"] =~ /0x15ad/
            result = "vmware" if output["spdisplays_vendor"] =~ /VM[wW]are/
        end
        result
    end
end


Facter.add("virtual") do
    confine :kernel => %w{Linux FreeBSD OpenBSD SunOS HP-UX GNU/kFreeBSD}

    result = "physical"

    setcode do

        if Facter::Util::Virtual.zone? and Facter.value(:operatingsystem) == "Solaris"
            result = "zone"
        end

        if Facter.value(:kernel)=="HP-UX"
            result = "hpvm" if Facter::Util::Virtual.hpvm?
        end

        if Facter.value(:architecture)=="s390x"
            result = "zlinux" if Facter::Util::Virtual.zlinux?
        end

        if Facter::Util::Virtual.openvz?
            result = Facter::Util::Virtual.openvz_type()
        end

        if Facter::Util::Virtual.vserver?
            result = Facter::Util::Virtual.vserver_type()
        end

        if Facter::Util::Virtual.xen?
            # new Xen domains have this in dom0 not domu :(
            if FileTest.exists?("/proc/sys/xen/independent_wallclock")
                result = "xenu"
            end
            if FileTest.exists?("/sys/bus/xen")
                result = "xenu"
            end

            if FileTest.exists?("/proc/xen/capabilities")
                txt = Facter::Util::Resolution.exec("cat /proc/xen/capabilities")
                if txt =~ /control_d/i
                    result = "xen0"
                end
            end
        end

        if Facter::Util::Virtual.kvm?
            result = Facter::Util::Virtual.kvm_type()
        end

        if ["FreeBSD", "GNU/kFreeBSD"].include? Facter.value(:kernel)
            result = "jail" if Facter::Util::Virtual.jail?
        end

        if result == "physical"
            output = Facter::Util::Resolution.exec('lspci')
            if not output.nil?
                output.each_line do |p|
                    # --- look for the vmware video card to determine if it is virtual => vmware.
                    # ---     00:0f.0 VGA compatible controller: VMware Inc [VMware SVGA II] PCI Display Adapter
                    result = "vmware" if p =~ /VM[wW]are/
                    # --- look for virtualbox video card to determine if it is virtual => virtualbox.
                    # ---     00:02.0 VGA compatible controller: InnoTek Systemberatung GmbH VirtualBox Graphics Adapter
                    result = "virtualbox" if p =~ /VirtualBox/
                    # --- look for pci vendor id used by Parallels video card
                    # ---   01:00.0 VGA compatible controller: Unknown device 1ab8:4005
                    result = "parallels" if p =~ /1ab8:|[Pp]arallels/
                end
            else
                output = Facter::Util::Resolution.exec('dmidecode')
                if not output.nil?
                    output.each_line do |pd|
                        result = "parallels" if pd =~ /Parallels/
                        result = "vmware" if pd =~ /VMware/
                        result = "virtualbox" if pd =~ /VirtualBox/
                    end
                else
                    output = Facter::Util::Resolution.exec('prtdiag')
                    if not output.nil?
                        output.each_line do |pd|
                            result = "parallels" if pd =~ /Parallels/
                            result = "vmware" if pd =~ /VMware/
							result = "virtualbox" if pd =~ /VirtualBox/
                        end
                    end
                end
            end
            
            if FileTest.exists?("/usr/lib/vmware/bin/vmware-vmx")
                result = "vmware_server"
            end
        end

        result
    end
end

# Fact: is_virtual
#
# Purpose: returning true or false for if a machine is virtualised or not.
#
# Resolution: The Xen domain 0 machine is virtualised to a degree, but is generally
# not viewed as being a virtual machine. This checks that the machine is not
# physical nor xen0, if that is the case, it is virtual.
#
# Caveats:
#

Facter.add("is_virtual") do
    confine :kernel => %w{Linux FreeBSD OpenBSD SunOS HP-UX Darwin GNU/kFreeBSD}

    setcode do
        if Facter.value(:virtual) != "physical" && Facter.value(:virtual) != "xen0"
            "true"
        else
            "false"
        end
    end
end