Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(FACT-2722) Add disks fact for Solaris #2027

Merged
merged 2 commits into from
Aug 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/facter/facts/solaris/disks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Facts
module Solaris
class Disks
FACT_NAME = 'disks'

def call_the_resolver
fact_value = Facter::Resolvers::Solaris::Disks.resolve(:disks)
Facter::ResolvedFact.new(FACT_NAME, fact_value)
end
end
end
end
2 changes: 2 additions & 0 deletions lib/facter/resolvers/load_averages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def post_resolve(fact_name)

def read_load_averages(fact_name)
require_relative 'utils/ffi/load_averages'

log.debug('loading cpu load averages')
@fact_list[:load_averages] = %w[1m 5m 15m].zip(Utils::Ffi::LoadAverages.read_load_averages).to_h

@fact_list[fact_name]
Expand Down
51 changes: 51 additions & 0 deletions lib/facter/resolvers/solaris/disks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

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

class << self
private

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

def read_disks_info(fact_name)
return unless File.executable?('/usr/bin/kstat')

log.debug('loading disks info')

kstat_output = Facter::Core::Execution.execute('/usr/bin/kstat sderr', logger: log)
return if kstat_output.empty?

@fact_list[fact_name] = parse(kstat_output)
end

def parse(kstat_output)
disks = {}

names = kstat_output.scan(/name:\s+(\w+)/).flatten
products = kstat_output.scan(/Product\s+(.+)/).flatten
vendors = kstat_output.scan(/Vendor\s+(\w+)/).flatten
sizes = kstat_output.scan(/Size\s+(\w+)/).flatten

names.each_with_index do |name, index|
disk_size = sizes[index].to_i
disks[name] = {
product: products[index],
size: Facter::FactsUtils::UnitConverter.bytes_to_human_readable(disk_size),
size_bytes: disk_size,
vendor: vendors[index]
}
end
disks
end
end
end
end
end
end
38 changes: 38 additions & 0 deletions spec/facter/facts/solaris/disks_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

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

let(:value) do
{
'sd0' => {
'product' => 'VMware IDE CDR00Revision',
'size' => '0 bytes',
'size_bytes' => 0,
'vendor' => 'NECVMWar'
},
'sd1' => {
'product' => 'Virtual disk Revision',
'size' => '20.00 GiB',
'size_bytes' => 21_474_836_480,
'vendor' => 'VMware'
}
}
end

before do
allow(Facter::Resolvers::Solaris::Disks).to receive(:resolve).with(:disks).and_return(value)
end

it 'calls Facter::Resolvers::Solaris::Disks' do
fact.call_the_resolver
expect(Facter::Resolvers::Solaris::Disks).to have_received(:resolve).with(:disks)
end

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

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

before do
allow(File).to receive(:executable?).with('/usr/bin/kstat').and_return(status)
allow(Facter::Core::Execution)
.to receive(:execute)
.with('/usr/bin/kstat sderr', logger: resolver.log)
.and_return(output)
end

after do
resolver.invalidate_cache
end

context 'when kstat is present and can retrieve information' do
let(:value) do
{
'sd0' => {
product: 'VMware IDE CDR00Revision',
size: '0 bytes',
size_bytes: 0,
vendor: 'NECVMWar'
},
'sd1' => {
product: 'Virtual disk Revision',
size: '20.00 GiB',
size_bytes: 21_474_836_480,
vendor: 'VMware'
}
}
end
let(:status) { true }
let(:output) { load_fixture('kstat_sderr').read }

it 'returns disks info' do
expect(resolver.resolve(:disks)).to eq(value)
end
end

context 'when kstat is not present' do
let(:output) { '' }
let(:status) { false }

it 'returns nil' do
expect(resolver.resolve(:disks)).to be_nil
end
end

context 'when kstat is present but fails' do
let(:output) { '' }
let(:status) { true }

it 'returns nil' do
expect(resolver.resolve(:disks)).to be_nil
end
end
end
39 changes: 39 additions & 0 deletions spec/fixtures/kstat_sderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module: sderr instance: 0
name: sd0,err class: device_error
Device Not Ready 0
Hard Errors 0
Illegal Request 1
Media Error 0
No Device 0
Non-Aligned Writes 0
Predictive Failure Analysis 0
Product VMware IDE CDR00Revision
Recoverable 0
Revision 1.00
Serial No
Size 0
Soft Errors 0
Transport Errors 0
Vendor NECVMWar
crtime 36.863598884
snaptime 10853.889452697

module: sderr instance: 1
name: sd1,err class: device_error
Device Not Ready 0
Hard Errors 0
Illegal Request 8
Media Error 0
No Device 0
Non-Aligned Writes 0
Predictive Failure Analysis 0
Product Virtual disk Revision
Recoverable 0
Revision 1.0
Serial No
Size 21474836480
Soft Errors 0
Transport Errors 0
Vendor VMware
crtime 36.668316603
snaptime 10853.889846855