Skip to content

Commit

Permalink
(FACT-2721) Added ldom resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastian-miclea committed Aug 18, 2020
1 parent 835641d commit 03adf43
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 0 deletions.
19 changes: 19 additions & 0 deletions lib/facter/facts/solaris/hypervisors/ldom.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Facts
module Solaris
module Hypervisors
class Ldom
FACT_NAME = 'hypervisors.ldom'

def call_the_resolver
fact_value = Facter::Resolvers::Solaris::Ldom.resolve(:a)
fact_value = fact_value[:available_bytes] if fact_value

[Facter::ResolvedFact.new(FACT_NAME, fact_value),
Facter::ResolvedFact.new(ALIASES, Facter::FactsUtils::UnitConverter.bytes_to_mb(fact_value), :legacy)]
end
end
end
end
end
37 changes: 37 additions & 0 deletions lib/facter/facts/solaris/virtual.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

module Facts
module Solaris
class Virtual
FACT_NAME = 'virtual'

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

def call_the_resolver
@log.debug('Solaris Virtual Resolver')

fact_value = check_ldom || check_zone || 'physical'

@log.debug("Fact value is: #{fact_value}")

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

def check_ldom
@log.debug('Checking LDoms')
Facter::Resolvers::Solaris::Ldom.resolve(:role_impl)
end

def check_zone
@log.debug('Checking LDoms')
zone_name = Facter::Resolvers::SolarisZoneName.resolve(:current_zone_name)

return if zone_name == 'global'

zone_name
end
end
end
end
53 changes: 53 additions & 0 deletions lib/facter/resolvers/solaris/ldom.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true

module Facter
module Resolvers
module Solaris
class Ldom < BaseResolver
@semaphore = Mutex.new
@fact_list ||= {}
class << self
private

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

def call_virtinfo(fact_name)
# return unless File.executable?('/usr/sbin/virtinfo')

virtinfo_output = Facter::Core::Execution.execute('/usr/sbin/virtinfo -a -p', logger: log)
return if virtinfo_output.empty?

output_hash = parse_output(virtinfo_output)
return if output_hash.empty?

@fact_list[:chassis_serial] = output_hash['DOMAINCHASSIS']&.[]('serialno').strip
@fact_list[:control_domain] = output_hash['DOMAINCONTROL']&.[]('name').strip
@fact_list[:domain_name] = output_hash['DOMAINNAME']&.[]('name').strip
@fact_list[:domain_uuid] = output_hash['DOMAINUUID']&.[]('uuid').strip
@fact_list[:role_control] = output_hash['DOMAINROLE']&.[]('control').strip
@fact_list[:role_io] = output_hash['DOMAINROLE']&.[]('io').strip
@fact_list[:role_root] = output_hash['DOMAINROLE']&.[]('root').strip
@fact_list[:role_service] = output_hash['DOMAINROLE']&.[]('service').strip
@fact_list[:role_impl] = output_hash['DOMAINROLE']&.[]('impl').strip

@fact_list[fact_name]
end

def parse_output(output)
result = {}
output.each_line do |line|
next unless line.include? 'DOMAIN'

x = line.split('|')
result[x.shift] = x.map { |f| f.split('=') }.to_h
end

result
end
end
end
end
end
end
49 changes: 49 additions & 0 deletions spec/facter/facts/solaris/virtual_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

describe Facts::Solaris::Virtual do
describe '#call_the_resolver' do
subject(:fact) { Facts::Solaris::Virtual.new }

context 'when no hypervisor is found' do
let(:vm) { 'physical' }

before do
allow(Facter::Resolvers::SolarisZoneName).to receive(:resolve).with(:current_zone_name).and_return(nil)
allow(Facter::Resolvers::Solaris::Ldom).to receive(:resolve).with(:role_impl).and_return(nil)
end

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

context 'when ldom hypervisor is found' do
let(:vm) { 'LDoms' }

before do
allow(Facter::Resolvers::SolarisZoneName).to receive(:resolve).with(:current_zone_name).and_return(nil)
allow(Facter::Resolvers::Solaris::Ldom).to receive(:resolve).with(:role_impl).and_return(vm)
end

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

context 'when zone hypervisor is found' do
let(:vm) { 'my_zone' }

before do
allow(Facter::Resolvers::SolarisZoneName).to receive(:resolve).with(:current_zone_name).and_return(vm)
allow(Facter::Resolvers::Solaris::Ldom).to receive(:resolve).with(:role_impl).and_return(nil)
end

it 'returns virtual fact as physical' do
expect(fact.call_the_resolver).to be_an_instance_of(Facter::ResolvedFact).and \
have_attributes(name: 'virtual', value: vm)
end
end
end
end
127 changes: 127 additions & 0 deletions spec/facter/resolvers/solaris/ldom_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# frozen_string_literal: true

describe Facter::Resolvers::Solaris::Ldom do
subject(:resolver) { Facter::Resolvers::Solaris::Ldom }

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

before do
resolver.instance_variable_set(:@log, log_spy)
allow(Facter::Core::Execution)
.to receive(:execute)
.with('/usr/sbin/virtinfo -a -p', logger: log_spy)
.and_return(output)
end

after do
resolver.invalidate_cache
end

context 'when syscall returns valid output' do
let(:output) { load_fixture('virtinfo').read }

it 'parses chassis_serial' do
expect(resolver.resolve(:chassis_serial)).to eq('AK00358110')
end

it 'parses control_domain' do
expect(resolver.resolve(:control_domain)).to eq('opdx-a0-sun2')
end

it 'parses domain_name' do
expect(resolver.resolve(:domain_name)).to eq('sol11-11')
end

it 'parses domain_uuid' do
expect(resolver.resolve(:domain_uuid)).to eq('415dfab4-c373-4ac0-9414-8bf00801fb72')
end

it 'parses role_control' do
expect(resolver.resolve(:role_control)).to eq('false')
end

it 'parses role_io' do
expect(resolver.resolve(:role_io)).to eq('false')
end

it 'parses role_root' do
expect(resolver.resolve(:role_root)).to eq('false')
end

it 'parses role_service' do
expect(resolver.resolve(:role_service)).to eq('false')
end
end

context 'when syscall returns invalid output' do
let(:output) { 'iNvAlId OuTpUt' }

it 'parses chassis_serial to nil' do
expect(resolver.resolve(:chassis_serial)).to be_nil
end

it 'parses control_domain to nil' do
expect(resolver.resolve(:control_domain)).to be_nil
end

it 'parses domain_name to nil' do
expect(resolver.resolve(:domain_name)).to be_nil
end

it 'parses domain_uuid to nil' do
expect(resolver.resolve(:domain_uuid)).to be_nil
end

it 'parses role_control to nil' do
expect(resolver.resolve(:role_control)).to be_nil
end

it 'parses role_io to nil' do
expect(resolver.resolve(:role_io)).to be_nil
end

it 'parses role_root to nil' do
expect(resolver.resolve(:role_root)).to be_nil
end

it 'parses role_service to nil' do
expect(resolver.resolve(:role_service)).to be_nil
end
end

context 'when syscall has no output' do
let(:output) { '' }

it 'parses chassis_serial to nil' do
expect(resolver.resolve(:chassis_serial)).to be_nil
end

it 'parses control_domain to nil' do
expect(resolver.resolve(:control_domain)).to be_nil
end

it 'parses domain_name to nil' do
expect(resolver.resolve(:domain_name)).to be_nil
end

it 'parses domain_uuid to nil' do
expect(resolver.resolve(:domain_uuid)).to be_nil
end

it 'parses role_control to nil' do
expect(resolver.resolve(:role_control)).to be_nil
end

it 'parses role_io to nil' do
expect(resolver.resolve(:role_io)).to be_nil
end

it 'parses role_root to nil' do
expect(resolver.resolve(:role_root)).to be_nil
end

it 'parses role_service to nil' do
expect(resolver.resolve(:role_service)).to be_nil
end
end
end
6 changes: 6 additions & 0 deletions spec/fixtures/virtinfo
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
VERSION 1.0
DOMAINROLE|impl=LDoms|control=false|io=false|service=false|root=false
DOMAINNAME|name=sol11-11
DOMAINUUID|uuid=415dfab4-c373-4ac0-9414-8bf00801fb72
DOMAINCONTROL|name=opdx-a0-sun2
DOMAINCHASSIS|serialno=AK00358110

0 comments on commit 03adf43

Please sign in to comment.