onering-report 0.6.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +57 -0
- data/Makefile +2 -0
- data/Rakefile +8 -0
- data/lib/etc/facter.list +19 -0
- data/lib/facter/onering_disk_smart.rb +38 -0
- data/lib/facter/onering_properties_chef.rb +41 -0
- data/lib/facter/onering_properties_haproxy.rb +155 -0
- data/lib/facter/onering_properties_id.rb +69 -0
- data/lib/facter/onering_properties_netstat.rb +94 -0
- data/lib/facter/onering_properties_network.rb +253 -0
- data/lib/facter/onering_properties_onering.rb +17 -0
- data/lib/facter/onering_properties_openvz.rb +17 -0
- data/lib/facter/onering_properties_physical.rb +87 -0
- data/lib/facter/onering_properties_services.rb +25 -0
- data/lib/facter/onering_properties_system.rb +18 -0
- data/lib/facter/onering_properties_virident.rb +93 -0
- data/lib/facter/onering_properties_xen.rb +32 -0
- data/lib/facter/onering_properties_zfs.rb +174 -0
- data/lib/reporter/default/properties_chef.rb +15 -0
- data/lib/reporter/default/properties_facter.rb +51 -0
- data/lib/reporter/default/properties_haproxy.rb +8 -0
- data/lib/reporter/default/properties_ipmi.rb +10 -0
- data/lib/reporter/default/properties_network.rb +63 -0
- data/lib/reporter/default/properties_ohai.rb +62 -0
- data/lib/reporter/default/properties_openvz.rb +12 -0
- data/lib/reporter/default/properties_physical.rb +10 -0
- data/lib/reporter/default/properties_services.rb +6 -0
- data/lib/reporter/default/properties_system_cpu.rb +30 -0
- data/lib/reporter/default/properties_system_disk_block.rb +35 -0
- data/lib/reporter/default/properties_system_disk_lvm.rb +73 -0
- data/lib/reporter/default/properties_system_disk_mounts.rb +46 -0
- data/lib/reporter/default/properties_system_disk_smart.rb +3 -0
- data/lib/reporter/default/properties_system_memory.rb +111 -0
- data/lib/reporter/default/properties_xen.rb +16 -0
- data/lib/reporter/default/stats_virident.rb +8 -0
- data/lib/reporter/default/stats_zfs.rb +8 -0
- data/onering-report.gemspec +18 -0
- metadata +126 -0
@@ -0,0 +1,174 @@
|
|
1
|
+
if Facter::Util::Resolution.which("zpool")
|
2
|
+
def sz_to_bytes(sz)
|
3
|
+
case sz[-1].chr
|
4
|
+
when 'K'
|
5
|
+
rv = sz[0..-2].to_f * (1024)
|
6
|
+
when 'M'
|
7
|
+
rv = sz[0..-2].to_f * (1024 ** 2)
|
8
|
+
when 'G'
|
9
|
+
rv = sz[0..-2].to_f * (1024 ** 3)
|
10
|
+
when 'T'
|
11
|
+
rv = sz[0..-2].to_f * (1024 ** 4)
|
12
|
+
when 'P'
|
13
|
+
rv = sz[0..-2].to_f * (1024 ** 5)
|
14
|
+
when 'E'
|
15
|
+
rv = sz[0..-2].to_f * (1024 ** 6)
|
16
|
+
when 'Z'
|
17
|
+
rv = sz[0..-2].to_f * (1024 ** 7)
|
18
|
+
when 'Y'
|
19
|
+
rv = sz[0..-2].to_f * (1024 ** 8)
|
20
|
+
else
|
21
|
+
rv = sz[0..-2].to_f
|
22
|
+
end
|
23
|
+
|
24
|
+
rv.to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
zfs = {
|
28
|
+
:filesystems => [],
|
29
|
+
:pools => [],
|
30
|
+
:snapshots => []
|
31
|
+
}
|
32
|
+
|
33
|
+
|
34
|
+
# =============================================================================
|
35
|
+
# POOLS
|
36
|
+
Facter::Util::Resolution.exec("zpool list -H").to_s.lines.each do |line|
|
37
|
+
pool, size, allocated, free, used_perc, dedup, health, altroot = line.strip.split(/\s+/)
|
38
|
+
zfs_pool = {
|
39
|
+
:name => pool,
|
40
|
+
:status => health.downcase,
|
41
|
+
:size => {
|
42
|
+
:total => sz_to_bytes(size),
|
43
|
+
:allocated => sz_to_bytes(allocated),
|
44
|
+
:free => sz_to_bytes(free),
|
45
|
+
:used => (sz_to_bytes(size) - sz_to_bytes(free)),
|
46
|
+
:percent_used => used_perc.delete('%').to_f
|
47
|
+
},
|
48
|
+
:deduplication_factor => dedup.delete('x').to_f,
|
49
|
+
:virtual_devices => {}
|
50
|
+
}
|
51
|
+
|
52
|
+
zfs_pool[:mountpoint] = altroot if altroot != '-'
|
53
|
+
vdevs = {}
|
54
|
+
current_vdev = nil
|
55
|
+
|
56
|
+
# get vdevs/devices
|
57
|
+
Facter::Util::Resolution.exec("zpool status -v #{pool}").to_s.lines.each do |line|
|
58
|
+
if line =~ /^\s*([a-z]+):\s+(.*)$/
|
59
|
+
case $1
|
60
|
+
when 'scan'
|
61
|
+
# scrub output
|
62
|
+
if $2 =~ /scrub repaired ([0-9]+) in ((?:[0-9]+d)?(?:[0-9]+h)?(?:[0-9]+m)) with ([0-9]+) errors on (.*)$/
|
63
|
+
zfs_pool[:scrub] ||= {}
|
64
|
+
zfs_pool[:scrub][:repaired] = $1.to_i
|
65
|
+
zfs_pool[:scrub][:errors] = $3.to_i
|
66
|
+
zfs_pool[:scrub][:completed_at] = DateTime.parse($4).strftime("%Y-%m-%d %H:%M:%S %z")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# vdev line
|
71
|
+
elsif line =~ /^\t ([a-z0-9]+)(?:-([0-9]+))\s+([A-Z]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s*$/
|
72
|
+
current_vdev = "#{$1}-#{$2}"
|
73
|
+
vdevs[current_vdev] = {
|
74
|
+
:name => "#{$1}-#{$2}",
|
75
|
+
:type => $1.to_sym,
|
76
|
+
:number => $2.to_i,
|
77
|
+
:status => $3.downcase,
|
78
|
+
:errors => {
|
79
|
+
:read => $4.to_i,
|
80
|
+
:write => $5.to_i,
|
81
|
+
:checksum => $6.to_i
|
82
|
+
},
|
83
|
+
:devices => []
|
84
|
+
}
|
85
|
+
|
86
|
+
# device line
|
87
|
+
elsif line =~ /^\t ([a-zA-Z0-9\-\_]+)\s+([A-Z]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s*$/
|
88
|
+
if File.symlink?("/dev/disk/by-id/#{$1}")
|
89
|
+
dev = File.expand_path(File.readlink("/dev/disk/by-id/#{$1}"), "/dev/disk/by-id")
|
90
|
+
elsif File.exists?("/dev/#{$1}")
|
91
|
+
dev = "/dev/#{$1}"
|
92
|
+
end
|
93
|
+
|
94
|
+
vdevs[current_vdev][:devices] << {
|
95
|
+
:name => $1,
|
96
|
+
:device => dev,
|
97
|
+
:errors => {
|
98
|
+
:read => $2.to_i,
|
99
|
+
:write => $3.to_i,
|
100
|
+
:checksum => $4.to_i
|
101
|
+
}
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
vdevs.each do |name, devs|
|
107
|
+
zfs_pool[:virtual_devices][name.split('-').first.to_sym] ||= []
|
108
|
+
zfs_pool[:virtual_devices][name.split('-').first.to_sym] << devs
|
109
|
+
end
|
110
|
+
|
111
|
+
zfs[:pools] << zfs_pool
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
# =============================================================================
|
118
|
+
# FILESYSTEMS
|
119
|
+
Facter::Util::Resolution.exec("zfs list -H").to_s.lines.each do |line|
|
120
|
+
filesystem, used, available, referenced, mountpoint = line.strip.split(/\s+/)
|
121
|
+
|
122
|
+
zfs_filesystem = {
|
123
|
+
:name => filesystem,
|
124
|
+
:mountpoint => mountpoint,
|
125
|
+
:properties => {},
|
126
|
+
:snapshots => [],
|
127
|
+
:size => {
|
128
|
+
:used => sz_to_bytes(used),
|
129
|
+
:free => sz_to_bytes(available)
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
# get properties
|
134
|
+
Facter::Util::Resolution.exec("zfs get all -H #{filesystem}").to_s.lines.each do |line|
|
135
|
+
fs, property, value, source = line.strip.split(/\t/)
|
136
|
+
|
137
|
+
value = case value
|
138
|
+
when 'off' then false
|
139
|
+
when 'on' then true
|
140
|
+
when 'none' then nil
|
141
|
+
when /^[0-9]+(?:\.[0-9]+)?[KMGTPEZY]$/ then sz_to_bytes(value)
|
142
|
+
when /^[0-9]+$/ then value.to_i
|
143
|
+
when /^[0-9]+\.[0-9]+$/ then value.to_f
|
144
|
+
when /^[0-9]+\.[0-9]+x$/ then value.delete('x').to_f
|
145
|
+
else value
|
146
|
+
end
|
147
|
+
|
148
|
+
zfs_filesystem[:properties][property.to_sym] = value
|
149
|
+
end
|
150
|
+
|
151
|
+
zfs[:filesystems] << zfs_filesystem
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
# =============================================================================
|
156
|
+
# SNAPSHOTS
|
157
|
+
Facter::Util::Resolution.exec("zfs list -H -t snapshot").to_s.lines.each do |line|
|
158
|
+
name, used, available, referenced, mountpoint = line.strip.split(/\s+/)
|
159
|
+
mountpoint = nil if mountpoint == '-'
|
160
|
+
|
161
|
+
zfs[:snapshots] << {
|
162
|
+
:name => name,
|
163
|
+
:used => sz_to_bytes(used),
|
164
|
+
:available => sz_to_bytes(available),
|
165
|
+
:referenced => sz_to_bytes(referenced),
|
166
|
+
:mountpoint => mountpoint
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
Facter.add("zfs") do
|
172
|
+
setcode{ zfs }
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Onering Collector - Chef Properties plugin
|
2
|
+
# provides collection of Chef metadata
|
3
|
+
#
|
4
|
+
report do
|
5
|
+
chef = {
|
6
|
+
:name => Facter.value('chef_nodename'),
|
7
|
+
:environment => Facter.value('chef_environment'),
|
8
|
+
:@run_list => Facter.value('chef_runlist'),
|
9
|
+
:enabled => Facter.value('chef_enabled'),
|
10
|
+
:version => Facter.value('chef_version'),
|
11
|
+
:last_ran_at => (Time.at(Facter.value('chef_lastrun')).strftime('%Y-%m-%d %H:%M:%S %z') rescue nil)
|
12
|
+
}.reject{|k,v| v === nil }
|
13
|
+
|
14
|
+
property :chef, chef unless chef.empty?
|
15
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Onering Collector - Facter Properties plugin
|
2
|
+
# provides a configurable list of Facter facts that should be sent to the
|
3
|
+
# Onering API
|
4
|
+
#
|
5
|
+
# Properties defined in /etc/onering/facter.list
|
6
|
+
#
|
7
|
+
|
8
|
+
report do
|
9
|
+
def cleanup_dirty_values(k, v)
|
10
|
+
return case k
|
11
|
+
when 'mbserial' then v.to_s.gsub(/(^\.+|\.+$)/,'').gsub('.','-')
|
12
|
+
else (v.strip.chomp rescue v)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
if defined?(Facter)
|
17
|
+
# get a list of Facter attributes to list
|
18
|
+
local_list = File.join(File.dirname(File.dirname(File.dirname(__FILE__))),'etc','facter.list')
|
19
|
+
|
20
|
+
facts = [
|
21
|
+
local_list,
|
22
|
+
"/etc/onering/facter.list"
|
23
|
+
].collect{|file|
|
24
|
+
IO.readlines(file) if File.exists?(file)
|
25
|
+
}.flatten.compact.uniq
|
26
|
+
|
27
|
+
|
28
|
+
facts.each do |line|
|
29
|
+
Onering::Logger.debug3("-> Facter Line: #{line.inspect}", "Onering::Reporter")
|
30
|
+
|
31
|
+
# strip whitespace/kill newline
|
32
|
+
line.strip!
|
33
|
+
line.chomp!
|
34
|
+
next if line.empty?
|
35
|
+
line = line.downcase
|
36
|
+
|
37
|
+
unless line =~ /^#/
|
38
|
+
begin
|
39
|
+
line = line.split(':')
|
40
|
+
key = (line.length == 1 ? line.first : line.last)
|
41
|
+
val = cleanup_dirty_values(key, Facter.value(line.first))
|
42
|
+
|
43
|
+
property(key.to_sym, val)
|
44
|
+
rescue Exception => e
|
45
|
+
Onering::Logger.debug(e.message, "onering-report-plugins/properties_facter/#{e.class.name}")
|
46
|
+
next
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Onering Collector - IPMI plugin
|
2
|
+
# provides collection of IPMI data using vendor tools
|
3
|
+
#
|
4
|
+
|
5
|
+
report do
|
6
|
+
property :ipmi_ip, Facter.value('ipmi_ip')
|
7
|
+
property :ipmi_netmask, Facter.value('ipmi_netmask')
|
8
|
+
property :ipmi_gateway, Facter.value('ipmi_gateway')
|
9
|
+
property :ipmi_macaddress, Facter.value('ipmi_macaddress')
|
10
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
report do
|
2
|
+
interfaces = {}
|
3
|
+
ips = []
|
4
|
+
|
5
|
+
Facter.value('network_interfaces').each do |iface|
|
6
|
+
iface = iface.to_sym
|
7
|
+
next if [:dummy0, :lo, :sit0].include?(iface)
|
8
|
+
interfaces[iface] ||= {}
|
9
|
+
|
10
|
+
mac = (Facter.value("macaddress_#{iface}").upcase rescue nil)
|
11
|
+
mtu = (Integer(Facter.value("mtu_#{iface}")) rescue nil)
|
12
|
+
|
13
|
+
interfaces[iface][:name] = iface
|
14
|
+
interfaces[iface][:mac] = mac if mac
|
15
|
+
interfaces[iface][:mtu] = mtu if mtu
|
16
|
+
|
17
|
+
ips << Facter.value("ipaddress_#{iface}")
|
18
|
+
|
19
|
+
addresses = [{
|
20
|
+
:ip => Facter.value("ipaddress_#{iface}"),
|
21
|
+
:netmask => Facter.value("netmask_#{iface}")
|
22
|
+
}.reject{|k,v| v.nil? }]
|
23
|
+
|
24
|
+
interfaces[iface][:addresses] = addresses unless addresses.empty? or addresses.reject{|i| i.empty? }.empty?
|
25
|
+
|
26
|
+
# LLDP autodiscovery
|
27
|
+
switch = {
|
28
|
+
:name => Facter.value("lldp_switch_#{iface}"),
|
29
|
+
:port => Facter.value("lldp_port_#{iface}"),
|
30
|
+
:speed => Facter.value("lldp_speed_#{iface}"),
|
31
|
+
:duplex => Facter.value("lldp_duplex_#{iface}"),
|
32
|
+
:port_name => Facter.value("lldp_port_name_#{iface}"),
|
33
|
+
:port_mac => Facter.value("lldp_port_mac_#{iface}"),
|
34
|
+
:ip => Facter.value("lldp_management_ip_#{iface}"),
|
35
|
+
:chassis_mac => Facter.value("lldp_chassis_mac_#{iface}"),
|
36
|
+
:vlan => Facter.value("lldp_vlan_#{iface}"),
|
37
|
+
:tagged_vlans => Facter.value("lldp_tagged_vlans_#{iface}")
|
38
|
+
}.reject{|k,v| v.nil? }
|
39
|
+
|
40
|
+
|
41
|
+
# Bonding configuration
|
42
|
+
|
43
|
+
# slaves
|
44
|
+
master = Facter.value("bonding_master_#{iface}")
|
45
|
+
interfaces[iface][:master] = master if master
|
46
|
+
|
47
|
+
# masters
|
48
|
+
bond = {
|
49
|
+
:arp_ip_target => Facter.value("bonding_arp_ip_target_#{iface}")
|
50
|
+
}.reject {|k,v| v.nil? }
|
51
|
+
|
52
|
+
|
53
|
+
# conditionally add applicable subsections
|
54
|
+
interfaces[iface][:switch] = switch unless switch.empty?
|
55
|
+
interfaces[iface][:bonding] = bond unless bond.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
property :network, {
|
59
|
+
:@ip => ips,
|
60
|
+
:@interfaces => interfaces.values,
|
61
|
+
:@sockets => Facter.value('netstat')
|
62
|
+
}
|
63
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Onering Collector - Ohai Properties plugin
|
2
|
+
# provides a configurable list of Ohai attributes that should be sent to the
|
3
|
+
# Onering API
|
4
|
+
#
|
5
|
+
# Properties defined in /etc/onering/ohai.list
|
6
|
+
#
|
7
|
+
|
8
|
+
report do
|
9
|
+
if defined?(Ohai)
|
10
|
+
def cleanup_dirty_values(k, v)
|
11
|
+
return case k
|
12
|
+
when 'mbserial' then v.to_s.gsub(/(^\.+|\.+$)/,'').gsub('.','-')
|
13
|
+
else v
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# get a list of ohai attributes to list
|
18
|
+
if File.exists?("/etc/onering/ohai.list")
|
19
|
+
IO.readlines("/etc/onering/ohai.list").each do |line|
|
20
|
+
# trip whitespace/kill newline
|
21
|
+
line.strip!
|
22
|
+
line.chomp!
|
23
|
+
next if line.empty?
|
24
|
+
line = line.downcase
|
25
|
+
|
26
|
+
unless line =~ /^#/
|
27
|
+
begin
|
28
|
+
parts = line.split(".")
|
29
|
+
root = @ohai
|
30
|
+
|
31
|
+
parts.each do |part|
|
32
|
+
part = part.split(':')
|
33
|
+
key = part.first
|
34
|
+
alt = part.last
|
35
|
+
|
36
|
+
if root[key]
|
37
|
+
if root[key].is_a?(Hash)
|
38
|
+
root = root[key]
|
39
|
+
next
|
40
|
+
else
|
41
|
+
val = [*root[key]].collect{|i| i.strip.chomp rescue i }
|
42
|
+
val = val.first if val.length == 1
|
43
|
+
val = cleanup_dirty_values(alt, val)
|
44
|
+
val.strip! if val.is_a?(String)
|
45
|
+
|
46
|
+
# set property value
|
47
|
+
property alt, val
|
48
|
+
break
|
49
|
+
end
|
50
|
+
else
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rescue Exception => e
|
55
|
+
Onering::Logger.warn("Error occurred gathering Ohai facts: #{e.class.name} - #{e.message}", "onering-report-plugins/properties_ohai")
|
56
|
+
next
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Onering Collector - OpenVZ Properties plugin
|
2
|
+
# provides collection of OpenVZ metadata
|
3
|
+
#
|
4
|
+
report do
|
5
|
+
vz_containers = Facter.value('openvz_containers')
|
6
|
+
vz = {}
|
7
|
+
|
8
|
+
# OpenVZ host
|
9
|
+
vz[:@guests] = vz_containers if vz_containers
|
10
|
+
|
11
|
+
property :openvz, vz unless vz.empty?
|
12
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Onering Collector - Physical Properties plugin
|
2
|
+
# provides collection of hardware location data using vendor tools
|
3
|
+
#
|
4
|
+
|
5
|
+
report do
|
6
|
+
property :site, Facter.value('site')
|
7
|
+
property :environment, Facter.value('environment')
|
8
|
+
property :slot, Facter.value('slot')
|
9
|
+
property :virtual, (Facter.value('is_virtual').to_s == 'true' ? true : false)
|
10
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
report do
|
2
|
+
# ------------------------------------------------------------------------------
|
3
|
+
# cpu
|
4
|
+
#
|
5
|
+
stats_cpu = {
|
6
|
+
:count => 0,
|
7
|
+
:processors => []
|
8
|
+
}
|
9
|
+
|
10
|
+
current_cpu = nil
|
11
|
+
|
12
|
+
File.open("/proc/cpuinfo").each do |line|
|
13
|
+
case line
|
14
|
+
when /processor\s+:\s(.+)/
|
15
|
+
current_cpu = $1.to_i
|
16
|
+
stats_cpu[:count] += 1
|
17
|
+
stats_cpu[:processors][current_cpu] = {
|
18
|
+
:number => current_cpu
|
19
|
+
}
|
20
|
+
when /cpu MHz\s+:\s(.+)/
|
21
|
+
stats_cpu[:processors][current_cpu][:speed] = $1.to_f
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
stat :cpu, ({
|
26
|
+
'count' => Facter.value('processorcount').to_i,
|
27
|
+
'physical' => Facter.value('physicalprocessorcount').to_i,
|
28
|
+
'speed' => stats_cpu[:processors].collect{|i| i[:speed] }.compact.uniq.sort{|a,b| a.to_f <=> b.to_f }.last.to_f
|
29
|
+
} rescue nil)
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
report do
|
2
|
+
# ------------------------------------------------------------------------------
|
3
|
+
# block devices
|
4
|
+
#
|
5
|
+
blocks = []
|
6
|
+
|
7
|
+
Facter.value('blockdevices').to_s.split(/\W+/).each do |dev|
|
8
|
+
|
9
|
+
block = {
|
10
|
+
:name => dev,
|
11
|
+
:device => (File.exists?("/dev/#{dev}") ? "/dev/#{dev}" : nil)
|
12
|
+
}
|
13
|
+
|
14
|
+
if File.directory?("/sys/block/#{dev}")
|
15
|
+
block[:vendor] = (%x{cat /sys/block/#{dev}/device/vendor 2> /dev/null}.to_s.strip.chomp rescue nil)
|
16
|
+
block[:model] = (%x{cat /sys/block/#{dev}/device/model 2> /dev/null}.to_s.strip.chomp rescue nil)
|
17
|
+
block[:size] = ((Integer(%x{cat /sys/block/#{dev}/size 2> /dev/null}.to_s.strip.chomp) * 512) rescue nil)
|
18
|
+
block[:removable] = (%x{cat /sys/block/#{dev}/removable 2> /dev/null}.to_s.chomp.strip == '1' rescue nil)
|
19
|
+
block[:readonly] = (%x{cat /sys/block/#{dev}/ro 2> /dev/null}.to_s.chomp.strip == '1' rescue nil)
|
20
|
+
block[:solidstate] = (%x{cat /sys/block/#{dev}/queue/rotational 2> /dev/null}.to_s.chomp.strip == '0' rescue nil)
|
21
|
+
block[:sectorsize] = {}
|
22
|
+
|
23
|
+
%w{
|
24
|
+
logical
|
25
|
+
physical
|
26
|
+
}.each do |s|
|
27
|
+
block[:sectorsize][s.to_sym] = (Integer(%x{cat /sys/block/#{dev}/queue/#{s}_block_size 2> /dev/null}.chomp.strip) rescue nil)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
blocks << block.compact
|
32
|
+
end
|
33
|
+
|
34
|
+
stat 'disk.@block', blocks
|
35
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
report do
|
2
|
+
# ------------------------------------------------------------------------------
|
3
|
+
# LVM
|
4
|
+
#
|
5
|
+
vg = {}
|
6
|
+
|
7
|
+
# volume groups
|
8
|
+
Facter::Util::Resolution.exec("vgdisplay -c 2> /dev/null").to_s.lines.each do |line|
|
9
|
+
line = line.strip.chomp.split(':')
|
10
|
+
|
11
|
+
vg[line[0]] = {
|
12
|
+
:name => line[0],
|
13
|
+
:uuid => line[16],
|
14
|
+
:size => (line[11].to_i*1024),
|
15
|
+
:extents => {
|
16
|
+
:size => (line[12].to_i * 1024),
|
17
|
+
:total => line[13].to_i,
|
18
|
+
:allocated => line[14].to_i,
|
19
|
+
:free => line[15].to_i
|
20
|
+
},
|
21
|
+
:volumes => [],
|
22
|
+
:disks => []
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
# logical volumes
|
27
|
+
Facter::Util::Resolution.exec("lvdisplay -c 2> /dev/null").to_s.lines.each do |line|
|
28
|
+
line = line.strip.chomp.split(':')
|
29
|
+
|
30
|
+
unless vg[line[1]].nil?
|
31
|
+
vg[line[1]][:volumes] << {
|
32
|
+
:name => line[0],
|
33
|
+
:sectors => line[6].to_i,
|
34
|
+
:extents => line[7].to_i,
|
35
|
+
:size => (vg[line[1]][:extents][:size] * line[7].to_i)
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# physical volumes
|
42
|
+
Facter::Util::Resolution.exec("pvdisplay -c 2> /dev/null").to_s.lines.each do |line|
|
43
|
+
line = line.strip.chomp.split(':')
|
44
|
+
|
45
|
+
unless vg[line[1]].nil?
|
46
|
+
vg[line[1]][:disks] << {
|
47
|
+
:name => line[0],
|
48
|
+
:uuid => line[11],
|
49
|
+
:size => (line[8].to_i * (line[7].to_i * 1024)), # See Note 1 below
|
50
|
+
:extents => {
|
51
|
+
:size => (line[7].to_i * 1024),
|
52
|
+
:total => line[8].to_i,
|
53
|
+
:allocated => line[10].to_i,
|
54
|
+
:free => line[9].to_i
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
# the output of certain versions of pvdisplay -c reports a blatantly incorrect
|
59
|
+
# physical volume total size. the workaround is to calculate the actual total size
|
60
|
+
# via (total extents * extent size)
|
61
|
+
#
|
62
|
+
# this may or may not be GPT related
|
63
|
+
#
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
lvm = {}
|
68
|
+
lvm = {
|
69
|
+
:groups => vg.values
|
70
|
+
} unless vg.values.empty?
|
71
|
+
|
72
|
+
stat 'disk.@lvm', lvm unless lvm.empty?
|
73
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
report do
|
2
|
+
# ------------------------------------------------------------------------------
|
3
|
+
# mounts
|
4
|
+
#
|
5
|
+
mounts = {}
|
6
|
+
current_dev = nil
|
7
|
+
|
8
|
+
uuids = Hash[Dir["/dev/disk/by-uuid/*"].collect{|i|
|
9
|
+
[File.expand_path(File.readlink(i), File.dirname(i)), File.basename(i)]
|
10
|
+
}]
|
11
|
+
|
12
|
+
File.read("/etc/mtab").lines.each do |line|
|
13
|
+
dev,mount,fstype,flags,dump,pass = line.split(/\s+/)
|
14
|
+
|
15
|
+
mounts[dev] = {
|
16
|
+
:mount => mount,
|
17
|
+
:device => dev,
|
18
|
+
:filesystem => fstype,
|
19
|
+
:flags => flags.split(/\s*,\s*/),
|
20
|
+
:uuid => uuids[dev]
|
21
|
+
}.compact
|
22
|
+
end
|
23
|
+
|
24
|
+
# logical space utilization
|
25
|
+
Facter::Util::Resolution.exec("df 2> /dev/null").to_s.lines.each do |line|
|
26
|
+
next if line =~ /^Filesystem/
|
27
|
+
parts = line.split(/\s+/)
|
28
|
+
|
29
|
+
if parts.length == 1
|
30
|
+
current_dev = parts.first
|
31
|
+
next
|
32
|
+
|
33
|
+
else
|
34
|
+
dev,kblk,used,free,percent,mount = parts
|
35
|
+
dev = current_dev if dev.empty?
|
36
|
+
next unless mounts[dev] and mounts[dev].is_a?(Hash)
|
37
|
+
|
38
|
+
mounts[dev][:used] = (used.to_i * 1024)
|
39
|
+
mounts[dev][:available] = (free.to_i * 1024)
|
40
|
+
mounts[dev][:total] = (mounts[dev][:available] + mounts[dev][:used])
|
41
|
+
mounts[dev][:percent_used] = percent.delete('%').to_i
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
stat 'disk.@mounts', (Hash[mounts.select{|k,v| k =~ /^\/dev\/((h|s|xv|v)d|mapper|vgc)/ }].values rescue nil)
|
46
|
+
end
|