This repository has been archived by the owner on Jun 19, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(maint) Add FreeBSD disks and partitions facts
Storage on FreeBSD is managed by GEOM, which expose the current storage topology as an XML tree through a sysctl. Get this XML tree to build relevant facts.
- Loading branch information
Showing
7 changed files
with
603 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# frozen_string_literal: true | ||
|
||
module Facts | ||
module Freebsd | ||
class Disks | ||
FACT_NAME = 'disks' | ||
|
||
def call_the_resolver | ||
disks = Facter::Resolvers::Freebsd::Geom.resolve(:disks) | ||
|
||
Facter::ResolvedFact.new(FACT_NAME, disks) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# frozen_string_literal: true | ||
|
||
module Facts | ||
module Freebsd | ||
class Partitions | ||
FACT_NAME = 'partitions' | ||
|
||
def call_the_resolver | ||
partitions = Facter::Resolvers::Freebsd::Geom.resolve(:partitions) | ||
|
||
Facter::ResolvedFact.new(FACT_NAME, partitions) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
# frozen_string_literal: true | ||
|
||
module Facter | ||
module Resolvers | ||
module Freebsd | ||
class Geom < BaseResolver | ||
@semaphore = Mutex.new | ||
@fact_list ||= {} | ||
|
||
class << self | ||
private | ||
|
||
def post_resolve(fact_name) | ||
@fact_list.fetch(fact_name) { read_facts(fact_name) } | ||
end | ||
|
||
def read_facts(fact_name) | ||
require_relative 'ffi/ffi_helper' | ||
require 'rexml/document' | ||
|
||
read_disks | ||
read_partitions | ||
|
||
@fact_list[fact_name] | ||
end | ||
|
||
def read_disks | ||
@fact_list[:disks] = {} | ||
|
||
each_geom_class_provider('DISK') do |provider| | ||
name = provider.get_text('./name').value | ||
|
||
@fact_list[:disks][name] = %i[read_model read_serial_number read_size].map do |x| | ||
send(x, provider) | ||
end.inject(:merge) | ||
end | ||
end | ||
|
||
def read_partitions | ||
@fact_list[:partitions] = {} | ||
|
||
each_geom_class_provider('PART') do |provider| | ||
name = provider.get_text('./name').value | ||
|
||
@fact_list[:partitions][name] = %i[read_partlabel read_partuuid read_size].map do |x| | ||
send(x, provider) | ||
end.inject(:merge) | ||
end | ||
end | ||
|
||
def each_geom_class_provider(geom_class_name, &block) | ||
REXML::XPath.each(geom_topology, "/mesh/class[name/text() = '#{geom_class_name}']/geom/provider", &block) | ||
end | ||
|
||
def read_size(provider) | ||
res = {} | ||
return res unless (mediasize = provider.get_text('mediasize')) | ||
|
||
mediasize = Integer(mediasize.value) | ||
|
||
res[:size_bytes] = mediasize | ||
res[:size] = Facter::FactsUtils::UnitConverter.bytes_to_human_readable(mediasize) | ||
res | ||
end | ||
|
||
def read_model(provider) | ||
res = {} | ||
return res unless (model = provider.get_text('./config/descr')) | ||
|
||
res[:model] = model.value | ||
res | ||
end | ||
|
||
def read_partlabel(provider) | ||
res = {} | ||
return res unless (rawuuid = provider.get_text('./config/label')) | ||
|
||
res[:partlabel] = rawuuid.value | ||
res | ||
end | ||
|
||
def read_partuuid(provider) | ||
res = {} | ||
return res unless (rawuuid = provider.get_text('./config/rawuuid')) | ||
|
||
res[:partuuid] = rawuuid.value | ||
res | ||
end | ||
|
||
def read_serial_number(provider) | ||
res = {} | ||
return res unless (serial_number = provider.get_text('./config/ident')) | ||
|
||
res[:serial_number] = serial_number.value | ||
res | ||
end | ||
|
||
def geom_topology | ||
@geom_topology ||= REXML::Document.new(geom_confxml) | ||
end | ||
|
||
def geom_confxml | ||
Facter::Freebsd::FfiHelper.sysctl_by_name(:string, 'kern.geom.confxml') | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# frozen_string_literal: true | ||
|
||
describe Facts::Freebsd::Disks do | ||
subject(:fact) { Facts::Freebsd::Disks.new } | ||
|
||
let(:disk) do | ||
{ | ||
'disks' => { | ||
'sda' => { | ||
'model' => 'Virtual disk', | ||
'size' => '20.00 GiB', | ||
'size_bytes' => 21_474_836_480, | ||
'vendor' => 'VMware' | ||
} | ||
} | ||
} | ||
end | ||
|
||
describe '#call_the_resolver' do | ||
before do | ||
allow(Facter::Resolvers::Freebsd::Geom).to receive(:resolve).with(:disks).and_return(disk) | ||
end | ||
|
||
it 'calls Facter::Resolvers::Freebsd::Disk' do | ||
fact.call_the_resolver | ||
expect(Facter::Resolvers::Freebsd::Geom).to have_received(:resolve).with(:disks) | ||
end | ||
|
||
it 'returns resolved fact with name disk and value' do | ||
expect(fact.call_the_resolver) | ||
.to be_an_instance_of(Facter::ResolvedFact) | ||
.and have_attributes(name: 'disks', value: disk) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# frozen_string_literal: true | ||
|
||
describe Facts::Freebsd::Partitions do | ||
subject(:fact) { Facts::Freebsd::Partitions.new } | ||
|
||
let(:partitions) do | ||
{ | ||
'ada0p1' => { | ||
'partlabel' => 'gptboot0', | ||
'partuuid' => '503d3458-c135-11e8-bd11-7d7cd061b26f', | ||
'size' => '512.00 KiB', | ||
'size_bytes' => 524_288 | ||
} | ||
} | ||
end | ||
|
||
describe '#call_the_resolver' do | ||
before do | ||
allow(Facter::Resolvers::Freebsd::Geom).to receive(:resolve).with(:partitions).and_return(partitions) | ||
end | ||
|
||
it 'calls Facter::Resolvers::Freebsd::Partitions' do | ||
fact.call_the_resolver | ||
expect(Facter::Resolvers::Freebsd::Geom).to have_received(:resolve).with(:partitions) | ||
end | ||
|
||
it 'returns resolved fact with name partitions and value' do | ||
expect(fact.call_the_resolver) | ||
.to be_an_instance_of(Facter::ResolvedFact) | ||
.and have_attributes(name: 'partitions', value: partitions) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# frozen_string_literal: true | ||
|
||
describe Facter::Resolvers::Freebsd::Geom do | ||
describe '#resolve' do | ||
subject(:resolver) { Facter::Resolvers::Freebsd::Geom } | ||
|
||
before do | ||
allow(Facter::Freebsd::FfiHelper).to receive(:sysctl_by_name) | ||
.with(:string, 'kern.geom.confxml') | ||
.and_return(load_fixture('kern.geom.confxml').read) | ||
end | ||
|
||
describe 'disks resolution' do | ||
let(:expected_output) do | ||
{ | ||
'ada0' => { | ||
model: 'Samsung SSD 850 PRO 512GB', | ||
serial_number: 'S250NXAG959927J', | ||
size: '476.94 GiB', | ||
size_bytes: 512_110_190_592 | ||
} | ||
} | ||
end | ||
|
||
it 'returns disks fact' do | ||
expect(resolver.resolve(:disks)).to eql(expected_output) | ||
end | ||
end | ||
|
||
describe 'partitions resolution' do | ||
let(:expected_output) do | ||
{ | ||
'ada0p1' => { | ||
partlabel: 'gptboot0', | ||
partuuid: '503d3458-c135-11e8-bd11-7d7cd061b26f', | ||
size: '512.00 KiB', | ||
size_bytes: 524_288 | ||
}, | ||
'ada0p2' => { | ||
partlabel: 'swap0', | ||
partuuid: '5048d40d-c135-11e8-bd11-7d7cd061b26f', | ||
size: '2.00 GiB', | ||
size_bytes: 2_147_483_648 | ||
}, | ||
'ada0p3' => { | ||
partlabel: 'zfs0', | ||
partuuid: '504f1547-c135-11e8-bd11-7d7cd061b26f', | ||
size: '474.94 GiB', | ||
size_bytes: 509_961_306_112 | ||
} | ||
} | ||
end | ||
|
||
it 'returns partitions fact' do | ||
expect(resolver.resolve(:partitions)).to eql(expected_output) | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.