On May 8, 2009, at 1:46 PM, [email protected] wrote:
>
> From: R.I.Pienaar <[email protected]>
>
>
> Signed-off-by: R.I.Pienaar <[email protected]>
> ---
> lib/facter/diskdrives.rb | 40 ++++++++
> lib/facter/util/diskdrives.rb | 214 ++++++++++++++++++++++++++++++++
> +++++++++
> 2 files changed, 254 insertions(+), 0 deletions(-)
> create mode 100644 lib/facter/diskdrives.rb
> create mode 100644 lib/facter/util/diskdrives.rb
>
> diff --git a/lib/facter/diskdrives.rb b/lib/facter/diskdrives.rb
> new file mode 100644
> index 0000000..90f66b4
> --- /dev/null
> +++ b/lib/facter/diskdrives.rb
> @@ -0,0 +1,40 @@
> +# diskdrives.rb
> +# Try to get additional Facts about the machine's disk drives
> +
> +require 'facter/util/diskdrives'
> +
> +Facter.add(:diskdrives) do
> + setcode do
> + Facter::Util::DiskDrives.get_drive_list.join(",")
> + end
> +end
> +
> +Facter::Util::DiskDrives.get_drive_sizes.each do |drive|
> + drive.each do |d, size|
> + Facter.add("disksize_#{d}") do
> + setcode do
> + size
> + end
> + end
> + end
> +end
> +
> +Facter::Util::DiskDrives.get_drive_types.each do |drive|
> + drive.each do |drive, type|
> + Facter.add("disktype_#{drive}") do
> + setcode do
> + type
> + end
> + end
> + end
> +end
> +
> +Facter::Util::DiskDrives.get_drive_models.each do |drive|
> + drive.each do |drive, model|
> + Facter.add("diskmodel_#{drive}") do
> + setcode do
> + model
> + end
> + end
> + end
> +end
Does the 'drive' in each of these refer to the same information?
Would it be possible to have one method that returns a hash of
information for each drive that you could then use to define your
facts? Something like:
Facter::Util::DiskDrives.drives.each do |name, data|
data.each do |param, value|
Facter.add("#{param}_#{name}") { setcode { value }}
end
end
Five lines of code isntead of 30 or so.
> diff --git a/lib/facter/util/diskdrives.rb b/lib/facter/util/
> diskdrives.rb
> new file mode 100644
> index 0000000..ba546aa
> --- /dev/null
> +++ b/lib/facter/util/diskdrives.rb
> @@ -0,0 +1,214 @@
> +# A base module for collecting Disk Drive-related
> +# information from all kinds of platforms.
> +module Facter::Util::DiskDrives
> + # All the types of drives we know about
> + DRIVETYPES = ["xvd", "ide", "scsi"]
> +
> + # platforms we work on
> + def self.supported_platforms
> + [:linux]
> + end
Is this used anywhere? Shouldn't it be used to confine the facts?
> + # fetch all known drive types and return a nice array
> + def self.get_drive_list
> + drivelist = []
> +
> + DRIVETYPES.each do |t|
> + eval("drivelist << self.get_#{t}_list")
I'd *much* prefer all of these evals use this form instead:
drivelist << send("get_#{t}_list")
We're refreshingly light on eval, and I'd like to keep it that way.
This is true for the evals below, too.
And really, this whole thing could be reduced to:
def self.get_drive_list
DRIVETYPES.collect { |t|
send("get_#{t}_list") }.compact.flattent.sort
end
None of these temporary variables are necessary.
>
> + end
> +
> + drivelist.compact.flatten.sort
> + end
> +
> + # finds out the sizes for all known drives
> + def self.get_drive_sizes
> + sizes = []
> +
> + DRIVETYPES.each do |t|
> + eval("sizes << self.get_#{t}_sizes")
> + end
> +
> + sizes.compact.flatten
> + end
> +
> + # finds out what type of drive each known drive is
> + def self.get_drive_types
> + drivetypes = []
> +
> + DRIVETYPES.each do |t|
> + drivelist = []
> + eval("drivelist << self.get_#{t}_list")
> +
> + drivelist.compact.flatten.each do |d|
> + drivetypes << {d, t} if d != nil
> + end
> + end
> +
> + drivetypes
> + end
> +
> + # find out the manufacturer/modelof each known drive
> + def self.get_drive_models
> + models = []
> + DRIVETYPES.each do |t|
> + eval("models << self.get_#{t}_models")
> + end
> +
> + models.compact.flatten
> + end
> +
> + # returns 'Xen Virtual Disk' for each xen disk
> + def self.get_xvd_models
> + case Facter.value(:kernel)
> + when 'Linux'
I'd just do 'return [] unless Facter.value(:kernel) == 'Linux''.
>
> + models = []
> + drives = self.get_xvd_list
> +
> + if drives
> + drives.each do |d|
> + models << {d, "Xen Virtual Disk"}
> + end
> + end
> +
> + models
> + end
> + end
> +
> + # returns the drive make for each SCSI disk
> + def self.get_scsi_models
> + case Facter.value(:kernel)
> + when 'Linux'
> + models = []
> + drives = self.get_scsi_list
> +
> + if drives
> + self.get_scsi_list.each do |d|
> + sfile = "/sys/block/#{d}/device/model"
> +
> + model = %x{/bin/cat #{sfile}}.chomp if
> File.exists?(sfile)
> +
> + models << {d => model} if models
> + end
> + end
> +
> + models
> + end
> + end
> +
> + # returns the drive make for each IDE disk
> + def self.get_ide_models
> + case Facter.value(:kernel)
> + when 'Linux'
> + models = []
> + drives = self.get_ide_list
> +
> + if drives
> + drives.each do |d|
> + sfile = "/proc/ide/#{d}/model"
> +
> + model = %x{/bin/cat #{sfile}}.chomp if
> File.exists?(sfile)
> +
> + models << {d => model} if models
> + end
> + end
> +
> + models
> + end
> + end
> +
> + # returns the size of each known Xen Virtual Disk
> + def self.get_xvd_sizes
> + case Facter.value(:kernel)
> + when 'Linux'
> + self.get_linux_block_sizes(self.get_xvd_list)
> + end
> + end
> +
> + # returns the size of each known SCSI Disk
> + def self.get_scsi_sizes
> + self.get_linux_block_sizes(self.get_scsi_list)
> + end
> +
> + # returns the size of each known IDE Disk
> + def self.get_ide_sizes
> + case Facter.value(:kernel)
> + when 'Linux'
The repetition of this pattern indicates to me that the fact
collection is a bit inside out: You're collecting all of the data
outside the Fact declarations, which means you can't use the 'confine'
statements.
If you can provide methods to get the appropriate data directly, then
you can confine your facts:
Facter::Util::DiskDrives.drives.each do |name, data|
data.each do |param, value|
Facter.add("#{param}_#{name}") do
confine :operatingsystem =>
Facter::Util::Drives.supported_platforms
setcode { Facter::Util::DiskDrives.get_drive_data(name, param) }
end
end
end
The only complication with this is that it results in duplication of
calls, once to define the facts and once to retrieve the value. It
simplifies your module considerably, though, and with the caching we
should be adding in 1.6 I think it will be easier to work around.
>
> + drives = self.get_ide_list
> + sizes = []
> +
> + if drives
> + drives.each do |d|
> + sfile = "/sys/block/#{d}/size"
> +
> + # this fails when running puppet as a daemon,
> unknown reason!
> + # size = File.open(sfile).gets.chomp if
> File.exists?(sfile)
> + size = %x{/bin/cat #{sfile}}.chomp if
> File.exists?(sfile)
> +
> + sizes << {d => size} if size
> + end
> + end
> +
> + sizes.size > 0 ? sizes : nil
> + end
> + end
> +
> + # reads size of all linux block devices passed as an argument
> + def self.get_linux_block_sizes(drives)
> + sizes = []
> +
> + if drives
> + drives.each do |d|
> + sfile = "/sys/block/#{d}/size"
> +
> + # this fails when running puppet as a daemon,
> unknown reason!
> + # size = File.open(sfile).gets.chomp if File.exists?
> (sfile)
> + size = %x{/bin/cat #{sfile}}.chomp if File.exists?
> (sfile)
> +
> + sizes << {d => size} if size
Why use an array of hashes, isntead of just a hash?
>
> + end
> + end
> +
> + sizes.size > 0 ? sizes : nil
> + end
> +
> + # returns a list of Xen Virtual Disks drives
> + def self.get_xvd_list
> + drives = []
> +
> + case Facter.value(:kernel)
> + when 'Linux'
> + sdir = "/sys/block"
> + drives = Dir.open(sdir).entries.grep(/^xv/) if
> File.exist?(sdir)
> + end
> +
> + drives.size > 0 ? drives : nil
> + end
> +
> + # returns a list of SCSI drives
> + def self.get_scsi_list
> + drives = []
> +
> + case Facter.value(:kernel)
> + when 'Linux'
> + sdir = "/sys/block"
> + drives = Dir.open(sdir).entries.grep(/^s/) if
> File.exist?(sdir)
> + end
> +
> + drives.size > 0 ? drives : nil
> + end
> +
> + # returns a list of IDE drives
> + def self.get_ide_list
> + drives = []
> +
> + case Facter.value(:kernel)
> + when 'Linux'
> + sdir = "/proc/ide"
> + drives = Dir.open(sdir).entries.grep(/^hd/) if
> File.exist?(sdir)
> + end
> +
> + drives.size > 0 ? drives : nil
> + end
> +end
> +
> +# vi:tabstop=4:expandtab:ai
> --
> 1.5.5.6
>
>
> >
--
Charm is a way of getting the answer yes without asking a clear
question. -- Albert Camus
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---