<commit_before>require 'allocator/namespace'
require 'allocator/policy_helpers'

module StackBuilder::Allocator::HostPolicies
  def self.ha_group()
    Proc.new do |host, machine_spec|
      result = { :passed => true }
      if machine_spec[:availability_group]
        host.machines.each do |allocated_machine|
          if allocated_machine[:availability_group] && machine_spec[:availability_group] == allocated_machine[:availability_group]
            result = { :passed => false, :reason => "Availability group violation (already running #{allocated_machine[:hostname]})" }
          end
        end
      end
      result
    end
  end

  def self.allocation_temporarily_disabled_policy
    Proc.new do |host, machine|
      result = { :passed => true }
      result = { :passed => false, :reason => "Allocation disabled" } if host.allocation_disabled
      result
    end
  end

  def self.do_not_overallocated_ram_policy
    helper = StackBuilder::Allocator::PolicyHelpers
    Proc.new do |host, machine|
      result = { :passed => true }
      host_ram_stats = helper.ram_stats_of(host)
      if host_ram_stats[:available_ram] < Integer(machine[:ram])
        result = {
          :passed => false,
          :reason => "Insufficient memory (required: #{machine[:ram]} KiB available: #{host_ram_stats[:available_ram]} KiB)"
        }
      end
      result
    end
  end

  def self.ensure_defined_storage_types_policy
    Proc.new do |host, machine|
      missing_storage_types = machine[:storage].inject([]) do |result, (mount_point, values)|
        # FIXME: remove the rescue once all compute nodes have storage config
        host_storage_type = host.storage[values[:type]] rescue nil
        result << values[:type] if host_storage_type.nil?
        result
      end
      result = { :passed => true }
      # FIXME: unwrap from unless once all compute nodes have storage config
      unless host.storage.nil?
        if missing_storage_types.any?
          unique_missing_storage_types = Set.new(missing_storage_types).to_a
          result = {
            :passed => false,
            :reason => "Storage type not available (required: #{unique_missing_storage_types.join(',')} available: #{host.storage.keys.sort.join(',')})"
          }
        end
      end
      result
    end
  end

  def self.check_storage_exists(mount_point)
    false
  end

  def self.require_persistent_storage_to_exist_policy
    Proc.new do |host, machine|
      result = { :passed => true }

      persistent_storage_not_found = {}
      if !host.storage.nil?
        machine[:storage].each do |mount_point, attributes|
          persistent = attributes[:persistent]
          persistence_options = attributes[:persistence_options] rescue {}
          on_storage_not_found = persistence_options[:on_storage_not_found] rescue :raise_error
          if persistent
            case on_storage_not_found
            when :raise_error
              underscore_name = "#{machine[:hostname]}#{mount_point.to_s.gsub('/', '_').gsub(/_$/, '')}"
              type = attributes[:type]
              if !host.storage.has_key?(type)
                persistent_storage_not_found[type] = [] unless persistent_storage_not_found.include? type
                persistent_storage_not_found[type] << underscore_name
              else
                unless host.storage[type][:existing_storage].include? underscore_name.to_sym
                  persistent_storage_not_found[type] = [] unless persistent_storage_not_found.include? type
                  persistent_storage_not_found[type] << underscore_name
                end
              end
            when :create_new
              # Allow the storage to be created
            end
          end
        end
        reasons = persistent_storage_not_found.keys.map do |type|
          "#{type}: #{persistent_storage_not_found[type].join(',')}"
        end
        unless persistent_storage_not_found.empty?
          result = {
            :passed => false,
            :reason => "Persistent storage not present for type #{reasons.join(',')}"
          }
        end

      end
      result
    end
  end

  def self.do_not_overallocate_disk_policy
    required_space_hash = {}
    Proc.new do |host, machine|
      machine[:storage].each do |mount_point, values|
        required_space_hash[values[:type]] = 0
      end
      machine[:storage].each do |mount_point, values|
        required_space_hash[values[:type]] += values[:size].to_f
      end
      storage_without_enough_space = required_space_hash.inject({}) do |result, (type, required_space)|
        host_storage_type = host.storage[type] rescue nil
        if !host_storage_type.nil?
          available_space = KB_to_GB(host_storage_type[:free])
          if required_space > available_space
            result[type] = { :available_space => available_space, :required_space => required_space }
          end
        else
          result[type] = { :available_space => 0, :required_space => required_space }
        end
        result
      end
      result = { :passed => true }
      if !storage_without_enough_space.empty?
        sorted_keys = storage_without_enough_space.keys.sort
        result = {
          :passed => false,
          :reason => "Insufficient disk space (required: #{sorted_keys.collect { |key| storage_without_enough_space[key][:required_space] }.join(',') }G available: #{sorted_keys.collect { |key| storage_without_enough_space[key][:available_space] }.join(',')}G)"
        }
      end
      result
    end
  end

  private

  def self.KB_to_GB(value)
    ((value.to_f / (1024 * 1024) * 100).round / 100.0)
  end
end<commit_msg>fix and enable rubocop Style/UnlessElse check - for real this time<commit_after>require 'allocator/namespace'
require 'allocator/policy_helpers'

module StackBuilder::Allocator::HostPolicies
  def self.ha_group()
    Proc.new do |host, machine_spec|
      result = { :passed => true }
      if machine_spec[:availability_group]
        host.machines.each do |allocated_machine|
          if allocated_machine[:availability_group] && machine_spec[:availability_group] == allocated_machine[:availability_group]
            result = { :passed => false, :reason => "Availability group violation (already running #{allocated_machine[:hostname]})" }
          end
        end
      end
      result
    end
  end

  def self.allocation_temporarily_disabled_policy
    Proc.new do |host, machine|
      result = { :passed => true }
      result = { :passed => false, :reason => "Allocation disabled" } if host.allocation_disabled
      result
    end
  end

  def self.do_not_overallocated_ram_policy
    helper = StackBuilder::Allocator::PolicyHelpers
    Proc.new do |host, machine|
      result = { :passed => true }
      host_ram_stats = helper.ram_stats_of(host)
      if host_ram_stats[:available_ram] < Integer(machine[:ram])
        result = {
          :passed => false,
          :reason => "Insufficient memory (required: #{machine[:ram]} KiB available: #{host_ram_stats[:available_ram]} KiB)"
        }
      end
      result
    end
  end

  def self.ensure_defined_storage_types_policy
    Proc.new do |host, machine|
      missing_storage_types = machine[:storage].inject([]) do |result, (mount_point, values)|
        # FIXME: remove the rescue once all compute nodes have storage config
        host_storage_type = host.storage[values[:type]] rescue nil
        result << values[:type] if host_storage_type.nil?
        result
      end
      result = { :passed => true }
      # FIXME: unwrap from unless once all compute nodes have storage config
      unless host.storage.nil?
        if missing_storage_types.any?
          unique_missing_storage_types = Set.new(missing_storage_types).to_a
          result = {
            :passed => false,
            :reason => "Storage type not available (required: #{unique_missing_storage_types.join(',')} available: #{host.storage.keys.sort.join(',')})"
          }
        end
      end
      result
    end
  end

  def self.check_storage_exists(mount_point)
    false
  end

  def self.require_persistent_storage_to_exist_policy
    Proc.new do |host, machine|
      result = { :passed => true }

      persistent_storage_not_found = {}
      if !host.storage.nil?
        machine[:storage].each do |mount_point, attributes|
          persistent = attributes[:persistent]
          persistence_options = attributes[:persistence_options] rescue {}
          on_storage_not_found = persistence_options[:on_storage_not_found] rescue :raise_error
          if persistent
            case on_storage_not_found
            when :raise_error
              underscore_name = "#{machine[:hostname]}#{mount_point.to_s.gsub('/', '_').gsub(/_$/, '')}"
              type = attributes[:type]
              if host.storage.has_key?(type)
                unless host.storage[type][:existing_storage].include? underscore_name.to_sym
                  persistent_storage_not_found[type] = [] unless persistent_storage_not_found.include? type
                  persistent_storage_not_found[type] << underscore_name
                end
              else
                persistent_storage_not_found[type] = [] unless persistent_storage_not_found.include? type
                persistent_storage_not_found[type] << underscore_name
              end
            when :create_new
              # Allow the storage to be created
            end
          end
        end
        reasons = persistent_storage_not_found.keys.map do |type|
          "#{type}: #{persistent_storage_not_found[type].join(',')}"
        end
        unless persistent_storage_not_found.empty?
          result = {
            :passed => false,
            :reason => "Persistent storage not present for type #{reasons.join(',')}"
          }
        end

      end
      result
    end
  end

  def self.do_not_overallocate_disk_policy
    required_space_hash = {}
    Proc.new do |host, machine|
      machine[:storage].each do |mount_point, values|
        required_space_hash[values[:type]] = 0
      end
      machine[:storage].each do |mount_point, values|
        required_space_hash[values[:type]] += values[:size].to_f
      end
      storage_without_enough_space = required_space_hash.inject({}) do |result, (type, required_space)|
        host_storage_type = host.storage[type] rescue nil
        if host_storage_type.nil?
          result[type] = { :available_space => 0, :required_space => required_space }
        else
          available_space = KB_to_GB(host_storage_type[:free])
          if required_space > available_space
            result[type] = { :available_space => available_space, :required_space => required_space }
          end
        end
        result
      end
      result = { :passed => true }
      if !storage_without_enough_space.empty?
        sorted_keys = storage_without_enough_space.keys.sort
        result = {
          :passed => false,
          :reason => "Insufficient disk space (required: #{sorted_keys.collect { |key| storage_without_enough_space[key][:required_space] }.join(',') }G available: #{sorted_keys.collect { |key| storage_without_enough_space[key][:available_space] }.join(',')}G)"
        }
      end
      result
    end
  end

  private

  def self.KB_to_GB(value)
    ((value.to_f / (1024 * 1024) * 100).round / 100.0)
  end
end
{'fraction_non_alphanumeric': 0.10065992080950285, 'fraction_numerical': 0.0029916410030796305, 'mean_word_length': 2.620898375278751, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2950698', 'n_tokens_mistral': 3298, 'n_tokens_neox': 3201, 'n_words': 708}