diff --git a/lib/facter/logical_volumes.rb b/lib/facter/logical_volumes.rb index da68c6cb..e3ac5946 100644 --- a/lib/facter/logical_volumes.rb +++ b/lib/facter/logical_volumes.rb @@ -26,9 +26,10 @@ 'lv_active', 'lv_size', 'lv_permissions', + 'vg_name', ] output = Facter::Core::Execution.exec("lvs -o #{columns.join(',')} --noheading --nosuffix") - Puppet_X::LVM::Output.parse('lv_name', columns, output) + Puppet_X::LVM::Output.parse('lv_name', columns, output, 'lv_') end end diff --git a/lib/facter/volume_group_map.rb b/lib/facter/volume_group_map.rb new file mode 100644 index 00000000..7ddc8cd1 --- /dev/null +++ b/lib/facter/volume_group_map.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +Facter.add(:volume_group_map) do + # Fact should be confined to only linux servers that have the vgs command + confine do + Facter.value('kernel') == 'Linux' && + Facter::Core::Execution.which('vgs') + end + + setcode do + Facter.value(:volume_groups).keys.to_h do |vg| + [ + vg, + Facter::Core::Execution.exec("vgs -o pv_name #{vg} --noheading --nosuffix") + .split("\n") + .map(&:strip) + .join(','), + ] + end + end +end diff --git a/lib/puppet_x/lvm/output.rb b/lib/puppet_x/lvm/output.rb index 6ab0a77b..abc0b45d 100644 --- a/lib/puppet_x/lvm/output.rb +++ b/lib/puppet_x/lvm/output.rb @@ -9,12 +9,12 @@ class Output # the data with the prefix removed i.e. "lv_free" would be come "free" # this however doesn't descriminate and will turn something like # "foo_bar" into "bar" - def self.parse(key, columns, data) + def self.parse(key, columns, data, prefix2remove = '[A-Za-z]+_') results = {} # Remove prefixes - columns = remove_prefixes(columns) - key = remove_prefix(key) + columns = remove_prefixes(columns, prefix2remove) + key = remove_prefix(key, prefix2remove) data.split("\n").each do |line| parsed_line = line.gsub(%r{\s+}, ' ').strip.split @@ -27,14 +27,14 @@ def self.parse(key, columns, data) results end - def self.remove_prefixes(array) + def self.remove_prefixes(array, prefix) array.map do |item| - remove_prefix(item) + remove_prefix(item, prefix) end end - def self.remove_prefix(item) - item.gsub(%r{^[A-Za-z]+_}, '') + def self.remove_prefix(item, prefix) + item.gsub(%r{^#{prefix}}, '') end end end diff --git a/spec/unit/facter/logical_volumes_spec.rb b/spec/unit/facter/logical_volumes_spec.rb index 6de5d6d2..f5e6a06d 100644 --- a/spec/unit/facter/logical_volumes_spec.rb +++ b/spec/unit/facter/logical_volumes_spec.rb @@ -36,12 +36,13 @@ Facter::Core::Execution.expects('which').with('lvs').returns('/sbin/lvs') end + # rubocop:disable RSpec/ExampleLength it 'is able to resolve VGs' do lvs_output = <<-OUTPUT - E7qan8-4NGf-jq2P-l11v-6fFe-MPHK-T6IGzl root centos/root /dev/centos/root /dev/mapper/centos-root -wi-ao---- linear public active 18.46g writeable - buUXDX-GDUh-rN2t-y80n-vtCt-xhhu-XSZ5kA swap centos/swap /dev/centos/swap /dev/mapper/centos-swap -wi-ao---- linear public active 1.00g writeable - uedsry-OTVv-wGW4-vaFf-c7IY-oH6Z-ig6IXB cool_tasks tasks/cool_tasks /dev/tasks/cool_tasks /dev/mapper/tasks-cool_tasks -wi-a----- linear public active 800.00m writeable - gmNS3G-cAhA-vRj0-2Uf0-21yO-QVdy-LNXfBv lame_tasks tasks/lame_tasks /dev/tasks/lame_tasks /dev/mapper/tasks-lame_tasks -wi-a----- linear public active 400.00m writeable + E7qan8-4NGf-jq2P-l11v-6fFe-MPHK-T6IGzl root centos/root /dev/centos/root /dev/mapper/centos-root -wi-ao---- linear public active 18.46g writeable centos + buUXDX-GDUh-rN2t-y80n-vtCt-xhhu-XSZ5kA swap centos/swap /dev/centos/swap /dev/mapper/centos-swap -wi-ao---- linear public active 1.00g writeable centos + uedsry-OTVv-wGW4-vaFf-c7IY-oH6Z-ig6IXB cool_tasks tasks/cool_tasks /dev/tasks/cool_tasks /dev/mapper/tasks-cool_tasks -wi-a----- linear public active 800.00m writeable tasks + gmNS3G-cAhA-vRj0-2Uf0-21yO-QVdy-LNXfBv lame_tasks tasks/lame_tasks /dev/tasks/lame_tasks /dev/mapper/tasks-lame_tasks -wi-a----- linear public active 400.00m writeable tasks OUTPUT lvs_output.dup.lstrip! Facter::Core::Execution.expects(:exec).at_least(1).returns(lvs_output) @@ -55,7 +56,8 @@ 'role' => 'public', 'active' => 'active', 'size' => '800.00m', - 'permissions' => 'writeable' + 'permissions' => 'writeable', + 'vg_name' => 'tasks' }, 'lame_tasks' => { 'uuid' => 'gmNS3G-cAhA-vRj0-2Uf0-21yO-QVdy-LNXfBv', @@ -67,7 +69,8 @@ 'role' => 'public', 'active' => 'active', 'size' => '400.00m', - 'permissions' => 'writeable' + 'permissions' => 'writeable', + 'vg_name' => 'tasks' }, 'root' => { 'uuid' => 'E7qan8-4NGf-jq2P-l11v-6fFe-MPHK-T6IGzl', @@ -79,7 +82,8 @@ 'role' => 'public', 'active' => 'active', 'size' => '18.46g', - 'permissions' => 'writeable' + 'permissions' => 'writeable', + 'vg_name' => 'centos' }, 'swap' => { 'uuid' => 'buUXDX-GDUh-rN2t-y80n-vtCt-xhhu-XSZ5kA', @@ -91,9 +95,11 @@ 'role' => 'public', 'active' => 'active', 'size' => '1.00g', - 'permissions' => 'writeable' + 'permissions' => 'writeable', + 'vg_name' => 'centos' }) end + # rubocop:enable RSpec/ExampleLength end end end diff --git a/spec/unit/facter/volume_group_map_spec.rb b/spec/unit/facter/volume_group_map_spec.rb new file mode 100644 index 00000000..a59001c3 --- /dev/null +++ b/spec/unit/facter/volume_group_map_spec.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'volume_group_map fact' do + before :each do + Facter.clear + end + + context 'when not on Linux' do + it 'is set to nil' do + Facter.fact(:kernel).expects(:value).at_least(1).returns('SunOs') + expect(Facter.value(:volume_group_map)).to be_nil + end + end + + context 'when on Linux' do + before :each do + Facter.fact(:kernel).expects(:value).at_least(1).returns('Linux') + end + + context 'when vgs is absent' do + before :each do + Facter::Core::Execution.stubs('exec') # All other calls + Facter::Core::Execution.expects('which').with('vgs').at_least(1).returns(nil) + end + + it 'is set to nil' do + expect(Facter.value(:volume_group_map)).to be_nil + end + end + + context 'when vgs is present' do + before :each do + Facter::Core::Execution.stubs('exec') # All other calls + Facter::Core::Execution.expects('which').with('vgs').at_least(1).returns('/sbin/vgs') + end + + it 'is able to resolve vgs and map pvs' do + Facter.fact(:volume_groups).expects(:value).returns( + { + 'centos' => { + 'uuid' => 'ZcFkEG-217a-nnc6-PvWx-oXou-7THt-XR6eci', + 'attr' => 'wz--n-', 'permissions' => 'writeable', + 'allocation_policy' => 'normal', + 'size' => '19.51g', + 'free' => '44.00m' + }, + 'tasks' => { + 'uuid' => 'tMqdQC-ukEx-bEft-bLk8-WoM1-jX0a-0p1rri', + 'attr' => 'wz--n-', + 'permissions' => 'writeable', + 'allocation_policy' => 'normal', + 'size' => '3.99g', + 'free' => '2.82g' + } + }, + ) + vgs_centos_output = <<-OUTPUT + /dev/sda + OUTPUT + vgs_centos_output.dup.lstrip! + Facter::Core::Execution.expects(:exec).at_least(1).with('vgs -o pv_name centos --noheading --nosuffix').returns(vgs_centos_output) + vgs_tasks_output = <<-OUTPUT + /dev/sdc + /dev/sdd2 + OUTPUT + vgs_tasks_output.dup.lstrip! + Facter::Core::Execution.expects(:exec).at_least(1).with('vgs -o pv_name tasks --noheading --nosuffix').returns(vgs_tasks_output) + + expect(Facter.value(:volume_group_map)).to include( + 'centos' => '/dev/sda', + 'tasks' => '/dev/sdc,/dev/sdd2', + ) + end + end + end +end