in cookbooks/fb_storage/libraries/format_devices_provider.rb [181:313]
def get_primary_work(storage)
needs_work = storage.out_of_spec
all_storage = storage.all_storage
stash_stats(needs_work)
Chef::Log.info(
"fb_storage: Out of spec storage: #{needs_work}",
)
Chef::Log.info(
"fb_storage: All storage: #{all_storage}",
)
format_rules = node['fb_storage']['format'].to_hash
bad_rules = format_rules.reject do |_, value|
[TrueClass, FalseClass].include?(value.class)
end
unless bad_rules.empty?
fail 'fb_storage: format rules must be booleans! ' +
"Fix #{bad_rules.keys}"
end
Chef::Log.info(
"fb_storage: Converge rules: #{format_rules}",
)
to_do = {
:devices => [], :partitions => [], :arrays => []
}
if erase_all?(format_rules)
return all_storage
elsif converge_all?(format_rules)
return filter_work(needs_work, :all, storage)
end
if format_rules['hotswap']
Chef::Log.info(
'fb_storage: Allowed to converge disks on this system ' +
'that external automation has specified',
)
storage.hotswap_disks.each do |disk|
unless storage.config[disk]
fail 'fb_storage: external automation says to repair disk ' +
"'#{disk}' but no config for this device exists"
end
end
devices = storage.hotswap_disks.reject do |disk|
storage.config[disk]['_skip']
end
partitions = devices.map do |disk|
FB::Storage.partition_names(
disk,
storage.config[disk],
)
end.flatten
arrays = []
Chef::Log.info(
'fb_storage: Determining what RAID0 arrays or Hybrid ' +
'XFS filesystems need rebuilding, and what arrays need to be ' +
'filled to accommodate automation request...',
)
partitions.each do |p|
storage.arrays.each do |array, info|
if (info['members'].include?(p) ||
info['journal']&.include?(p)) &&
['hybrid_xfs', 0].include?(info['raid_level'])
arrays << array
end
end
end
arrays.uniq!
unless arrays.empty?
Chef::Log.info(
'fb_storage: The following RAID0 arrays must be ' +
"rebuilt because a member disk has been replaced: #{arrays}",
)
end
to_do = merge_work(
to_do,
{
:devices => devices,
:partitions => partitions + arrays,
:arrays => arrays,
},
)
end
if format_rules['missing_filesystem_or_partition']
Chef::Log.debug(
'fb_storage: Allowed to converge disks with missing ' +
'partitions or filesystems on this system',
)
to_do = merge_work(to_do, filter_work(needs_work, :missing, storage))
end
if format_rules['mismatched_filesystem_or_partition']
Chef::Log.warn(
'fb_storage: Allowed to converge disks incorrect ' +
'partitions or filesystems on this system',
)
to_do = merge_work(to_do, filter_work(needs_work, :all, storage))
elsif format_rules['mismatched_filesystem_only']
Chef::Log.warn(
'fb_storage: Allowed to converge disks incorrect ' +
'filesystems on this system',
)
to_do = merge_work(to_do, filter_work(needs_work, :filesystems,
storage))
end
partitions_set = Set.new(to_do[:partitions])
(
needs_work[:missing_arrays] + needs_work[:mismatched_arrays]
).each do |array|
next if to_do[:arrays].include?(array)
if Set.new(storage.arrays[array]['members']) <= partitions_set
to_do[:arrays] << array
end
end
to_do
end