get_primary_work

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