Skip to content
This repository has been archived by the owner on Jun 19, 2020. It is now read-only.

Commit

Permalink
(FACT-2604) Add virt-what resolver (#523)
Browse files Browse the repository at this point in the history
  • Loading branch information
oanatmaria authored May 25, 2020
1 parent 5997ad6 commit f6a9a6c
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 1 deletion.
7 changes: 6 additions & 1 deletion lib/facts/linux/virtual.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ class Virtual
FACT_NAME = 'virtual'

def call_the_resolver
fact_value = check_docker_lxc || check_gce || check_vmware
fact_value = check_docker_lxc || check_gce || retrieve_from_virt_what || check_vmware

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

Expand All @@ -22,6 +23,10 @@ def check_docker_lxc
def check_vmware
Facter::Resolvers::Vmware.resolve(:vm)
end

def retrieve_from_virt_what
Facter::Resolvers::VirtWhat.resolve(:vm)
end
end
end
end
64 changes: 64 additions & 0 deletions lib/resolvers/virt_what.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# frozen_string_literal: true

module Facter
module Resolvers
class VirtWhat < BaseResolver
@semaphore = Mutex.new
@fact_list ||= {}

class << self
private

def post_resolve(fact_name)
@fact_list.fetch(fact_name) { retrieve_from_virt_what(fact_name) }
end

def retrieve_from_virt_what(fact_name)
output = Facter::Core::Execution.execute('virt-what', logger: log)

@fact_list[:vm] = determine_xen(output)
@fact_list[:vm] ||= determine_other(output)
retrieve_vserver unless @fact_list[:vserver]

@fact_list[fact_name]
end

def determine_xen(output)
xen_info = /^xen\n.*/.match(output)

return unless xen_info

xen_info = xen_info.to_s
return 'xenu' if xen_info =~ /xen-domu/
return 'xenhvm' if xen_info =~ /xen-hvm/
return 'xen0' if xen_info =~ /xen-dom0/
end

def determine_other(output)
other_vm = output.split("\n").first
return unless other_vm

return 'zlinux' if other_vm =~ /ibm_systemz/
return retrieve_vserver if other_vm =~ /linux_vserver/

other_vm
end

def retrieve_vserver
proc_status_content = Facter::Util::FileHelper.safe_readlines('/proc/self/status', nil)
return unless proc_status_content

proc_status_content.each do |line|
parts = line.split("\s")
next unless parts.size.equal?(2)

next unless parts[0] =~ /^s_context:|^VxID:/
return @fact_list[:vserver] = 'vserver_host' if parts[1] == '0'

return @fact_list[:vserver] = 'vserver'
end
end
end
end
end
end
15 changes: 15 additions & 0 deletions spec/facter/facts/linux/virtual_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@
end
end

context 'when is xen-hvm' do
let(:vm) { nil }
let(:value) { 'xenhvm' }

before do
allow(Facter::Resolvers::Linux::DmiBios).to receive(:resolve).with(:bios_vendor).and_return(nil)
allow(Facter::Resolvers::VirtWhat).to receive(:resolve).with(:vm).and_return(value)
end

it 'returns virtual fact' do
expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact).and \
have_attributes(name: 'virtual', value: value)
end
end

context 'when resolver returns nil' do
let(:vm) { nil }

Expand Down
57 changes: 57 additions & 0 deletions spec/facter/resolvers/virt_what_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

describe Facter::Resolvers::VirtWhat do
subject(:virt_what_resolver) { Facter::Resolvers::VirtWhat }

let(:log_spy) { instance_spy(Facter::Log) }

after do
virt_what_resolver.invalidate_cache
end

before do
virt_what_resolver.instance_variable_set(:@log, log_spy)
allow(Facter::Core::Execution).to receive(:execute).with('virt-what', logger: log_spy).and_return(content)
end

context 'when virt-what fails' do
let(:content) { '' }

it 'returns nil' do
expect(virt_what_resolver.resolve(:vm)).to be_nil
end
end

context 'when virt-what detects xen hypervisor' do
let(:content) { load_fixture('virt-what-content').read }
let(:result) { 'xenhvm' }

it 'returns virtual fact' do
expect(virt_what_resolver.resolve(:vm)).to eq(result)
end
end

context 'when virt-what detects vserver' do
let(:content) { 'linux_vserver' }
let(:result) { 'vserver_host' }
let(:proc_status_content) { load_fixture('proc_self_status').readlines }

before do
allow(Facter::Util::FileHelper).to receive(:safe_readlines).with('/proc/self/status', nil)
.and_return(proc_status_content)
end

it 'returns virtual fact' do
expect(virt_what_resolver.resolve(:vm)).to eq(result)
end
end

context 'when virt-what detects kvm' do
let(:content) { 'kvm' }
let(:result) { 'kvm' }

it 'returns virtual fact' do
expect(virt_what_resolver.resolve(:vm)).to eq(result)
end
end
end
17 changes: 17 additions & 0 deletions spec/fixtures/proc_self_status
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Name: cat
Umask: 0002
State: R (running)
Tgid: 14437
Ngid: 0
Pid: 14437
PPid: 14122
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
FDSize: 256
Groups: 4 20 24 25 27 29 30 44 46 108 114 1000
NStgid: 14437
NSpid: 14437
NSpgid: 14437
NSsid: 14122
VxID: 0
3 changes: 3 additions & 0 deletions spec/fixtures/virt-what-content
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
xen
xen-hvm
aws

0 comments on commit f6a9a6c

Please sign in to comment.