Skip to content

Commit

Permalink
Add vmware fact and update dmidecode resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
BogdanIrimie committed Jul 10, 2020
1 parent 353bf71 commit ace9b67
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 6 deletions.
38 changes: 38 additions & 0 deletions lib/facter/facts/linux/hypervisors/vmware.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

module Facts
module Linux
module Hypervisors
class Vmware
FACT_NAME = 'hypervisors.vmware'

def initialize
@log = Facter::Log.new(self)
end

def call_the_resolver
if vmware?
@log.debug('Vmware hypervisor detected')
fact_value = {}

fact_value[:version] = Facter::Resolvers::DmiDecode.resolve(:vmware_version) || ''

return Facter::ResolvedFact.new(FACT_NAME, fact_value)
end

@log.debug('No Vmware hypervisor detected.')
[]
end

private

def vmware?
Facter::Resolvers::VirtWhat.resolve(:vm) == 'vmware' ||
Facter::Resolvers::Linux::DmiBios.resolve(:product_name) == 'VMware' ||
Facter::Resolvers::Lspci.resolve(:vm) == 'vmware' ||
Facter::Resolvers::Linux::DmiBios.resolve(:sys_vendor) == 'VMware, Inc.'
end
end
end
end
end
27 changes: 27 additions & 0 deletions lib/facter/resolvers/dmi_decode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ class DmiDecode < BaseResolver
@semaphore = Mutex.new
@fact_list ||= {}

ADDRESS_TO_VERSION = {
0xe8480 => 'ESXi 2.5',
0xe7c70 => 'ESXi 3.0',
0xe66c0 => 'ESXi 3.5',
0xe7910 => 'ESXi 3.5',
0xea550 => 'ESXi 4.0',
0xea6c0 => 'ESXi 4.0',
0xea2e0 => 'ESXi 4.1',
0xe72c0 => 'ESXi 5.0',
0xea0c0 => 'ESXi 5.1',
0xea050 => 'ESXi 5.5',
0xe99e0 => 'ESXi 6.0',
0xE9A40 => 'ESXi 6.0',
0xea580 => 'ESXi 6.5',
0xEA520 => 'ESXi 6.7',
0xEA490 => 'ESXi 6.7',
0xea5e0 => 'Fusion 8.5'
}.freeze

class << self
private

Expand All @@ -18,8 +37,16 @@ def run_dmidecode(fact_name)

@fact_list[:virtualbox_version] = output.match(/vboxVer_(\S+)/)&.captures&.first
@fact_list[:virtualbox_revision] = output.match(/vboxRev_(\S+)/)&.captures&.first
@fact_list[:vmware_version] = extract_vmware_version(output)

@fact_list[fact_name]
end

def extract_vmware_version(output)
address_of_version = output.match(/Address:\s(0x[a-zA-Z0-9]*)/)&.captures&.first

ADDRESS_TO_VERSION[address_of_version&.hex]
end
end
end
end
Expand Down
76 changes: 76 additions & 0 deletions spec/facter/facts/linux/hypervisors/vmware_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# frozen_string_literal: true

describe Facts::Linux::Hypervisors::Vmware do
subject(:fact) { Facts::Linux::Hypervisors::Vmware.new }

describe '#call_the_resolver' do
context 'when vmware is detected' do
context 'when VirtWhat resolver returns vmware' do
before do
allow(Facter::Resolvers::VirtWhat).to receive(:resolve).with(:vm).and_return('vmware')
allow(Facter::Resolvers::DmiDecode).to receive(:resolve).with(:vmware_version).and_return('ESXi 6.7')
end

it 'returns vmware' do
expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact)
.and have_attributes(name: 'hypervisors.vmware', value: { 'version' => 'ESXi 6.7' })
end
end

context 'when DmiBios resolver with product_name returns VMware' do
before do
allow(Facter::Resolvers::VirtWhat).to receive(:resolve).with(:vm).and_return('unknown')
allow(Facter::Resolvers::Linux::DmiBios).to receive(:resolve).with(:product_name).and_return('VMware')
allow(Facter::Resolvers::DmiDecode).to receive(:resolve).with(:vmware_version).and_return('ESXi 6.7')
end

it 'returns vmware' do
expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact)
.and have_attributes(name: 'hypervisors.vmware', value: { 'version' => 'ESXi 6.7' })
end
end

context 'when Lspci resolver returns vmware' do
before do
allow(Facter::Resolvers::VirtWhat).to receive(:resolve).with(:vm).and_return('unknown')
allow(Facter::Resolvers::Linux::DmiBios).to receive(:resolve).with(:product_name).and_return('unknown')
allow(Facter::Resolvers::Lspci).to receive(:resolve).with(:vm).and_return('vmware')
allow(Facter::Resolvers::DmiDecode).to receive(:resolve).with(:vmware_version).and_return('ESXi 6.7')
end

it 'returns vmware' do
expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact)
.and have_attributes(name: 'hypervisors.vmware', value: { 'version' => 'ESXi 6.7' })
end
end

context 'when DmiBios resolver with sys_vendor returns VMware, Inc.' do
before do
allow(Facter::Resolvers::VirtWhat).to receive(:resolve).with(:vm).and_return('unknown')
allow(Facter::Resolvers::Linux::DmiBios).to receive(:resolve).with(:product_name).and_return('unknown')
allow(Facter::Resolvers::Lspci).to receive(:resolve).with(:vm).and_return('unknown')
allow(Facter::Resolvers::Linux::DmiBios).to receive(:resolve).with(:sys_vendor).and_return('VMware, Inc.')
allow(Facter::Resolvers::DmiDecode).to receive(:resolve).with(:vmware_version).and_return('ESXi 6.7')
end

it 'returns vmware' do
expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact)
.and have_attributes(name: 'hypervisors.vmware', value: { 'version' => 'ESXi 6.7' })
end
end
end

context 'when vmware is not detected' do
before do
allow(Facter::Resolvers::VirtWhat).to receive(:resolve).with(:vm).and_return('unknown')
allow(Facter::Resolvers::Linux::DmiBios).to receive(:resolve).with(:product_name).and_return('unknown')
allow(Facter::Resolvers::Lspci).to receive(:resolve).with(:vm).and_return('unknown')
allow(Facter::Resolvers::Linux::DmiBios).to receive(:resolve).with(:sys_vendor).and_return('unknown')
end

it 'returns empty list' do
expect(fact.call_the_resolver).to eq([])
end
end
end
end
34 changes: 28 additions & 6 deletions spec/facter/resolvers/dmi_decode_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,43 @@
describe '#resolve' do
subject(:dmidecode) { Facter::Resolvers::DmiDecode }

let(:command_output) { load_fixture('dmi_decode').read }

before do
allow(Facter::Core::Execution).to receive(:execute)
.with('dmidecode', logger: instance_of(Facter::Log)).and_return(command_output)
end

after { dmidecode.invalidate_cache }

it 'detects virtualbox version' do
expect(dmidecode.resolve(:virtualbox_version)).to eql('6.1.4')
context 'when virtualbox hypervisor' do
let(:command_output) { load_fixture('dmi_decode_virtualbox').read }

it 'detects virtualbox version' do
expect(dmidecode.resolve(:virtualbox_version)).to eql('6.1.4')
end

it 'detects virtualbox revision' do
expect(dmidecode.resolve(:virtualbox_revision)).to eql('136177')
end

it 'does not detect vmware_version' do
expect(dmidecode.resolve(:vmware_version)).to be_nil
end
end

it 'detects virtualbox revision' do
expect(dmidecode.resolve(:virtualbox_revision)).to eql('136177')
context 'when vmware hypervisor' do
let(:command_output) { load_fixture('dmi_decode_vmware').read }

it 'does not detects virtualbox version' do
expect(dmidecode.resolve(:virtualbox_version)).to be_nil
end

it 'does not detect detects virtualbox revision' do
expect(dmidecode.resolve(:virtualbox_revision)).to be_nil
end

it 'detect vmware_version' do
expect(dmidecode.resolve(:vmware_version)).to eq('ESXi 6.7')
end
end

context 'when dmidecode command failed' do
Expand Down
File renamed without changes.
130 changes: 130 additions & 0 deletions spec/fixtures/dmi_decode_vmware
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
Getting SMBIOS data from sysfs.
SMBIOS 2.7 present.
242 structures occupying 9908 bytes.
Table at 0x000E0010.

Handle 0x0000, DMI type 0, 24 bytes
BIOS Information
Vendor: Phoenix Technologies LTD
Version: 6.00
Release Date: 12/12/2018
Address: 0xEA490
Runtime Size: 88944 bytes
ROM Size: 64 kB
Characteristics:
ISA is supported
PCI is supported
PC Card (PCMCIA) is supported
PNP is supported
APM is supported
BIOS is upgradeable
BIOS shadowing is allowed
ESCD support is available
Boot from CD is supported
Selectable boot is supported
EDD is supported
Print screen service is supported (int 5h)
8042 keyboard services are supported (int 9h)
Serial services are supported (int 14h)
Printer services are supported (int 17h)
CGA/mono video services are supported (int 10h)
ACPI is supported
Smart battery is supported
BIOS boot specification is supported
Function key-initiated network boot is supported
Targeted content distribution is supported
BIOS Revision: 4.6
Firmware Revision: 0.0

Handle 0x0001, DMI type 1, 27 bytes
System Information
Manufacturer: VMware, Inc.
Product Name: VMware Virtual Platform
Version: None
Serial Number: VMware-42 1a ee 9a 8e 13 ee e5-fc ec 82 3d cd 74 76 94
UUID: 9aee1a42-138e-e5ee-fcec-823dcd747694
Wake-up Type: Power Switch
SKU Number: Not Specified
Family: Not Specified

Handle 0x0002, DMI type 2, 15 bytes
Base Board Information
Manufacturer: Intel Corporation
Product Name: 440BX Desktop Reference Platform
Version: None
Serial Number: None
Asset Tag: Not Specified
Features: None
Location In Chassis: Not Specified
Chassis Handle: 0x0000
Type: Unknown
Contained Object Handles: 0

Handle 0x0003, DMI type 3, 21 bytes
Chassis Information
Manufacturer: No Enclosure
Type: Other
Lock: Not Present
Version: N/A
Serial Number: None
Asset Tag: No Asset Tag
Boot-up State: Safe
Power Supply State: Safe
Thermal State: Safe
Security Status: None
OEM Information: 0x00001234
Height: Unspecified
Number Of Power Cords: Unspecified
Contained Elements: 0

Handle 0x0004, DMI type 4, 42 bytes
Processor Information
Socket Designation: CPU #000
Type: Central Processor
Family: Unknown
Manufacturer: GenuineIntel
ID: 54 06 05 00 FF FB 8B 0F
Version: Intel(R) Xeon(R) Gold 6138 CPU @ 2.00GHz
Voltage: 3.3 V
External Clock: Unknown
Max Speed: 30000 MHz
Current Speed: 2000 MHz
Status: Populated, Enabled
Upgrade: ZIF Socket
L1 Cache Handle: 0x0016
L2 Cache Handle: 0x0018
L3 Cache Handle: Not Provided
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Core Count: 1
Core Enabled: 1
Characteristics:
64-bit capable
Execute Protection

Handle 0x0004, DMI type 4, 42 bytes
Processor Information
Socket Designation: CPU #001
Type: Central Processor
Family: Unknown
Manufacturer: GenuineIntel
ID: 54 06 00 00 FF FB 8B 0F
Version: Intel(R) Xeon(R) Gold 6138 CPU @ 2.00GHz
Voltage: 3.3 V
External Clock: Unknown
Max Speed: 30000 MHz
Current Speed: 2000 MHz
Status: Populated, Enabled
Upgrade: ZIF Socket
L1 Cache Handle: 0x0016
L2 Cache Handle: 0x0018
L3 Cache Handle: Not Provided
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Core Count: 1
Core Enabled: 1
Characteristics:
64-bit capable
Execute Protection

0 comments on commit ace9b67

Please sign in to comment.