From 29e6a16236eb46652f03332d58d661831664b94e Mon Sep 17 00:00:00 2001 From: Joshua Hoblitt Date: Mon, 14 Apr 2014 16:27:56 -0700 Subject: [PATCH 1/2] add megaraid_physical_drives_{sata,sas} facts --- lib/facter/megaraid_physical_drives_sas.rb | 35 ++++++++++ lib/facter/megaraid_physical_drives_sata.rb | 35 ++++++++++ .../megaraid_physical_drives_sas_spec.rb | 67 +++++++++++++++++++ .../megaraid_physical_drives_sata_spec.rb | 67 +++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 lib/facter/megaraid_physical_drives_sas.rb create mode 100644 lib/facter/megaraid_physical_drives_sata.rb create mode 100644 spec/unit/facts/megaraid_physical_drives_sas_spec.rb create mode 100644 spec/unit/facts/megaraid_physical_drives_sata_spec.rb diff --git a/lib/facter/megaraid_physical_drives_sas.rb b/lib/facter/megaraid_physical_drives_sas.rb new file mode 100644 index 0000000..c7a2dae --- /dev/null +++ b/lib/facter/megaraid_physical_drives_sas.rb @@ -0,0 +1,35 @@ +Facter.add(:megaraid_physical_drives_sas) do + confine :kernel => 'Linux' + + setcode do + megacli = Facter.value(:megacli) + megaraid_adapters = Facter.value(:megaraid_adapters) + + if megacli.nil? || + megaraid_adapters.nil? || (megaraid_adapters == 0) + next nil + end + + # XXX there is no support for handling more than one adapter + pds = [] + list = Facter::Util::Resolution.exec("#{megacli} -PDList -aALL -NoLog") + next if list.nil? + + dev_id = nil + list.each_line do |line| + if line =~ /^Device Id:\s+(\d+)/ + dev_id = $1 + end + if line =~ /^PD Type:\s+(\w+)/ + type = $1 + if type == 'SAS' + pds.push(dev_id) + end + end + end + + # sort the device IDs numerically on the assumption that they are always + # integers + pds.sort {|a,b| a.to_i <=> b.to_i}.join(",") + end +end diff --git a/lib/facter/megaraid_physical_drives_sata.rb b/lib/facter/megaraid_physical_drives_sata.rb new file mode 100644 index 0000000..4ace0fc --- /dev/null +++ b/lib/facter/megaraid_physical_drives_sata.rb @@ -0,0 +1,35 @@ +Facter.add(:megaraid_physical_drives_sata) do + confine :kernel => 'Linux' + + setcode do + megacli = Facter.value(:megacli) + megaraid_adapters = Facter.value(:megaraid_adapters) + + if megacli.nil? || + megaraid_adapters.nil? || (megaraid_adapters == 0) + next nil + end + + # XXX there is no support for handling more than one adapter + pds = [] + list = Facter::Util::Resolution.exec("#{megacli} -PDList -aALL -NoLog") + next if list.nil? + + dev_id = nil + list.each_line do |line| + if line =~ /^Device Id:\s+(\d+)/ + dev_id = $1 + end + if line =~ /^PD Type:\s+(\w+)/ + type = $1 + if type == 'SATA' + pds.push(dev_id) + end + end + end + + # sort the device IDs numerically on the assumption that they are always + # integers + pds.sort {|a,b| a.to_i <=> b.to_i}.join(",") + end +end diff --git a/spec/unit/facts/megaraid_physical_drives_sas_spec.rb b/spec/unit/facts/megaraid_physical_drives_sas_spec.rb new file mode 100644 index 0000000..d4e6354 --- /dev/null +++ b/spec/unit/facts/megaraid_physical_drives_sas_spec.rb @@ -0,0 +1,67 @@ +require 'spec_helper' + +describe 'megaraid_physical_drives_sas', :type => :fact do + before(:each) { Facter.clear } + + describe 'on linux' do + context 'megacli not in path' do + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns(nil) + + Facter.fact(:megaraid_physical_drives_sas).value.should be_nil + end + end + + context 'megacli is broken' do + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns('/usr/bin/MegaCli') + Facter.fact(:megaraid_adapters).stubs(:value).returns(nil) + + Facter.fact(:megaraid_physical_drives_sas).value.should be_nil + end + + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns('/usr/bin/MegaCli') + Facter.fact(:megaraid_adapters).stubs(:value).returns('1') + Facter::Util::Resolution.stubs(:exec).with('/usr/bin/MegaCli -PDList -aALL -NoLog'). + returns(nil) + + Facter.fact(:megaraid_physical_drives_sas).value.should be_nil + end + end + + context 'no adapters' do + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns('/usr/bin/MegaCli') + Facter.fact(:megaraid_adapters).stubs(:value).returns('0') + + Facter.fact(:megaraid_physical_drives_sas).value.should be_nil + end + end + + context '1 adapter' do + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns('/usr/bin/MegaCli') + Facter.fact(:megaraid_adapters).stubs(:value).returns('1') + Facter::Util::Resolution.stubs(:exec).with('/usr/bin/MegaCli -PDList -aALL -NoLog'). + returns(File.read(fixtures('megacli', 'pdlistaall'))) + + Facter.fact(:megaraid_physical_drives_sas).value.should == '188,189,190,192,194,197,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214' + end + end + end # on linux + + context 'not on linux' do + it do + Facter.fact(:kernel).stubs(:value).returns('Solaris') + + Facter.fact(:megaraid_physical_drives_sas).value.should be_nil + end + end # not on linux +end + diff --git a/spec/unit/facts/megaraid_physical_drives_sata_spec.rb b/spec/unit/facts/megaraid_physical_drives_sata_spec.rb new file mode 100644 index 0000000..74a6813 --- /dev/null +++ b/spec/unit/facts/megaraid_physical_drives_sata_spec.rb @@ -0,0 +1,67 @@ +require 'spec_helper' + +describe 'megaraid_physical_drives_sata', :type => :fact do + before(:each) { Facter.clear } + + describe 'on linux' do + context 'megacli not in path' do + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns(nil) + + Facter.fact(:megaraid_physical_drives_sata).value.should be_nil + end + end + + context 'megacli is broken' do + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns('/usr/bin/MegaCli') + Facter.fact(:megaraid_adapters).stubs(:value).returns(nil) + + Facter.fact(:megaraid_physical_drives_sata).value.should be_nil + end + + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns('/usr/bin/MegaCli') + Facter.fact(:megaraid_adapters).stubs(:value).returns('1') + Facter::Util::Resolution.stubs(:exec).with('/usr/bin/MegaCli -PDList -aALL -NoLog'). + returns(nil) + + Facter.fact(:megaraid_physical_drives_sata).value.should be_nil + end + end + + context 'no adapters' do + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns('/usr/bin/MegaCli') + Facter.fact(:megaraid_adapters).stubs(:value).returns('0') + + Facter.fact(:megaraid_physical_drives_sata).value.should be_nil + end + end + + context '1 adapter' do + it do + Facter.fact(:kernel).stubs(:value).returns('Linux') + Facter.fact(:megacli).stubs(:value).returns('/usr/bin/MegaCli') + Facter.fact(:megaraid_adapters).stubs(:value).returns('1') + Facter::Util::Resolution.stubs(:exec).with('/usr/bin/MegaCli -PDList -aALL -NoLog'). + returns(File.read(fixtures('megacli', 'pdlistaall'))) + + Facter.fact(:megaraid_physical_drives_sata).value.should == '10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,184,185' + end + end + end # on linux + + context 'not on linux' do + it do + Facter.fact(:kernel).stubs(:value).returns('Solaris') + + Facter.fact(:megaraid_physical_drives_sata).value.should be_nil + end + end # not on linux +end + From 824e0869f2cce8cd9c557f1774880a080c3d70eb Mon Sep 17 00:00:00 2001 From: Joshua Hoblitt Date: Mon, 14 Apr 2014 16:47:06 -0700 Subject: [PATCH 2/2] change smartd.conf ERB to use megaraid_physical_drives_{sas,sata} facts This modification add ssupport for polling the SMART values of SAS drives behind a MegaRAID controller. The `megaraid_physical_drives` fact is no longer used internally by this module. --- spec/classes/smartd_spec.rb | 71 +++++++++++++++++++++++++++++++------ templates/smartd.conf | 20 +++++++---- 2 files changed, 74 insertions(+), 17 deletions(-) diff --git a/spec/classes/smartd_spec.rb b/spec/classes/smartd_spec.rb index c89fcc7..47568f5 100644 --- a/spec/classes/smartd_spec.rb +++ b/spec/classes/smartd_spec.rb @@ -430,14 +430,14 @@ describe 'megaraid support' do - describe 'without params + megaraid facts' do + describe 'without params + megaraid sata facts' do let(:facts) do { - :osfamily => 'RedHat', - :megaraid_adapters => '1', - :megaraid_virtual_drives => 'sdb,sda', - :megaraid_physical_drives => '2,1', - :smartmontools_version => '5.43', + :osfamily => 'RedHat', + :megaraid_adapters => '1', + :megaraid_virtual_drives => 'sdb,sda', + :megaraid_physical_drives_sata => '2,1', + :smartmontools_version => '5.43', } end @@ -453,14 +453,63 @@ end end + describe 'without params + megaraid sas facts' do + let(:facts) do + { + :osfamily => 'RedHat', + :megaraid_adapters => '1', + :megaraid_virtual_drives => 'sdb,sda', + :megaraid_physical_drives_sas => '2,1', + :smartmontools_version => '5.43', + } + end + + it do + should contain_file('/etc/smartd.conf')\ + .with_content(<<-END.gsub(/^\s+/, "")) + # Managed by Puppet -- do not edit! + DEFAULT -m root -M daily + /dev/sda -d megaraid,1 + /dev/sda -d megaraid,2 + DEVICESCAN + END + end + end + + describe 'without params + megaraid sata+sas facts' do + let(:facts) do + { + :osfamily => 'RedHat', + :megaraid_adapters => '1', + :megaraid_virtual_drives => 'sdb,sda', + :megaraid_physical_drives_sas => '1,2', + :megaraid_physical_drives_sata => '3,4', + :smartmontools_version => '5.43', + } + end + + it do + should contain_file('/etc/smartd.conf')\ + .with_content(<<-END.gsub(/^\s+/, "")) + # Managed by Puppet -- do not edit! + DEFAULT -m root -M daily + /dev/sda -d sat+megaraid,3 + /dev/sda -d sat+megaraid,4 + /dev/sda -d megaraid,1 + /dev/sda -d megaraid,2 + DEVICESCAN + END + end + end + describe 'with params + megaraid facts' do let(:facts) do { - :osfamily => 'RedHat', - :megaraid_adapters => '1', - :megaraid_virtual_drives => 'sdb,sda', - :megaraid_physical_drives => '2,1', - :smartmontools_version => '5.43', + :osfamily => 'RedHat', + :megaraid_adapters => '1', + :megaraid_virtual_drives => 'sdb,sda', + :megaraid_physical_drives_sata => '2,1', + :smartmontools_version => '5.43', } end let(:params) do diff --git a/templates/smartd.conf b/templates/smartd.conf index ca989cd..a0cff64 100644 --- a/templates/smartd.conf +++ b/templates/smartd.conf @@ -17,13 +17,21 @@ end # if there is an entry for megaraid device options fish it out megaraid_options = nil @devices.each { |dev| dev['device'] == 'megaraid' ? megaraid_options = dev['options'] : nil } - -if megaraid_device and megaraid_device != '' and - @megaraid_adapters and @megaraid_adapters.to_i > 0 - @megaraid_physical_drives.split(/,/).sort.each do |drive| -%> +-%> +<% if megaraid_device and megaraid_device != '' and + @megaraid_adapters and @megaraid_adapters.to_i > 0 -%> + <%- unless @megaraid_physical_drives_sata.nil? -%> + <%- @megaraid_physical_drives_sata.split(/,/).sort.each do |drive| -%> <%= megaraid_device %> -d sat+megaraid,<%= drive.to_i -%> -<% if megaraid_options %><%= ' ' + megaraid_options %><% end %> -<% end -%> + <%- if megaraid_options %><%= ' ' + megaraid_options %><% end %> + <%- end -%> + <%- end -%> + <%- unless @megaraid_physical_drives_sas.nil? -%> + <%- @megaraid_physical_drives_sas.split(/,/).sort.each do |drive| -%> +<%= megaraid_device %> -d megaraid,<%= drive.to_i -%> + <%- if megaraid_options %><%= ' ' + megaraid_options %><% end %> + <%- end -%> + <%- end -%> <% end -%> <% if @devicescan -%> <% unless @enable_default -%>