128 lines
3.8 KiB
Ruby
128 lines
3.8 KiB
Ruby
#
|
|
# partitions.rb
|
|
# BY kwilczynski (https://github.com/kwilczynski/facter-facts/blob/master/partitions.rb)
|
|
# This fact provides an alphabetic list of blocks per disk and/or partition,
|
|
# partitions per disk and disks.
|
|
#
|
|
# We support most of generic SATA and PATA disks, plus Hewlett-Packard
|
|
# Smart Array naming format ... This also should work for systems running
|
|
# as Virtual Machine guest at least for Xen and KVM ...
|
|
#
|
|
|
|
if Facter.value(:kernel) == 'Linux'
|
|
# We store a list of disks (or block devices if you wish) here ...
|
|
disks = []
|
|
|
|
# We store number of blocks per disk and/or partition here ...
|
|
blocks = {}
|
|
|
|
# We store a list of partitions on per-disk basis here ...
|
|
partitions = Hash.new { |k,v| k[v] = [] }
|
|
|
|
#
|
|
# Support for the following might not be of interest ...
|
|
#
|
|
# MMC is Multi Media Card which can be either SD or microSD, etc ...
|
|
# MTD is Memory Technology Device also known as Flash Memory
|
|
#
|
|
exclude = %w(backdev.* dm-\d loop mmcblk mtdblock ram ramzswap)
|
|
|
|
#
|
|
# Modern Linux kernels provide "/proc/partitions" in the following format:
|
|
#
|
|
# major minor #blocks name
|
|
#
|
|
# 8 0 244198584 sda
|
|
# 8 1 3148708 sda1
|
|
# 8 2 123804922 sda2
|
|
# 8 3 116214210 sda3
|
|
# 8 4 1028160 sda4
|
|
#
|
|
|
|
# Make regular expression form our patterns ...
|
|
exclude = Regexp.union(*exclude.collect { |i| Regexp.new(i) })
|
|
|
|
#
|
|
# We utilise rely on "cat" for reading values from entries under "/proc".
|
|
# This is due to some problems with IO#read in Ruby and reading content of
|
|
# the "proc" file system that was reported more than once in the past ...
|
|
#
|
|
Facter::Util::Resolution.exec('cat /proc/partitions 2> /dev/null').each_line do |line|
|
|
# Remove bloat ...
|
|
line.strip!
|
|
|
|
# Line of interest should start with a number ...
|
|
next if line.empty? or line.match(/^[a-zA-Z]+/)
|
|
|
|
# We have something, so let us apply our device type filter ...
|
|
next if line.match(exclude)
|
|
|
|
# Only blocks and partitions matter ...
|
|
block = line.split(/\s+/)[2]
|
|
partition = line.split(/\s+/)[3]
|
|
|
|
if partition.match(/^cciss/)
|
|
#
|
|
# Special case for Hewlett-Packard Smart Array which probably
|
|
# nobody is using any more nowadays anyway ...
|
|
#
|
|
partition = partition.split('/')[1]
|
|
|
|
if match = partition.match(/^([a-zA-Z0-9]+)[pP][0-9]+/)
|
|
# Handle the case when "cciss/c0d0p1" is given ...
|
|
disk = match[1]
|
|
elsif partition.match(/^[a-zA-Z0-9]+/)
|
|
# Handle the case when "cciss/c0d0" is given ...
|
|
disk = partition
|
|
end
|
|
else
|
|
# Take care of any partitions create atop of the
|
|
# Linux Software RAID decies like e.g. /dev/md0, etc.
|
|
if match = partition.match(/^(md\d+)/)
|
|
disk = match[1]
|
|
else
|
|
# Everything else ...
|
|
disk = partition.scan(/^[a-zA-Z]+/)
|
|
end
|
|
end
|
|
|
|
# Convert back into a string value ...
|
|
disk = Array(disk).first.to_s
|
|
|
|
# We have something rather odd that did not parse at all, so ignore ...
|
|
next if disk.empty?
|
|
|
|
# All disks ... This might even be sda, sdaa, sdab, sdac, etc ...
|
|
disks << disk
|
|
|
|
# Store details about number of blocks per disk and/or partition ...
|
|
blocks[partition] = block
|
|
|
|
# A disk is not a partition, therefore we ignore ...
|
|
partitions[disk] << partition unless partition == disk
|
|
end
|
|
|
|
Facter.add('disks') do
|
|
confine :kernel => :linux
|
|
setcode { disks.sort.uniq.join(',') }
|
|
end
|
|
|
|
blocks.each do |k,v|
|
|
Facter.add("blocks_#{k}") do
|
|
confine :kernel => :linux
|
|
setcode { v }
|
|
end
|
|
end
|
|
|
|
partitions.each do |k,v|
|
|
Facter.add("partitions_#{k}") do
|
|
confine :kernel => :linux
|
|
|
|
# To ensure proper sorting order by the interface name ...
|
|
v = v.sort_by { |i| i.scan(/\d+/).shift.to_i }
|
|
|
|
setcode { v.sort.join(',') }
|
|
end
|
|
end
|
|
end
|