-
Notifications
You must be signed in to change notification settings - Fork 17
/
partitions.rb
130 lines (107 loc) · 3.76 KB
/
partitions.rb
1
2
3
4
5
6
7
8
9
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#
# 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
# vim: set ts=2 sw=2 et :
# encoding: utf-8