app/models/vim_performance_analysis.rb
# This method answers C&U Planning question 2
This method answers C&U Planning question 2
This method answers C&U Planning question 2
def vm_how_many_more_can_fit(options = {})
      options ||= @options
      vm_needs   = get_vm_needs
      result     = []
      return result, vm_needs if @compute.blank?
      if @compute.first.kind_of?(EmsCluster)
        @hosts_to_cluster = {}
        MiqPreloader.preload(@compute, :hosts => [:hardware, {:vms => :hardware}])
        compute_hosts = @compute.collect do |c|
          c.hosts.each { |h| @hosts_to_cluster[h.id] = c }
          c.hosts
        end.flatten
      else
        MiqPreloader.preload(@compute, [:hardware, {:vms => :hardware}])
        compute_hosts = @compute
      end
      if VimPerformanceAnalysis.needs_perf_data?(options[:target_options])
        perf_cols = [:cpu, :vcpus, :memory, :storage].collect do |t|
          [options[:target_options].fetch_path(t, :metric), options[:target_options].fetch_path(t, :limit_col)]
        end.flatten.compact
      end
      result = compute_hosts.collect do |c|
        count_hash = {}
        compute_perf = VimPerformanceAnalysis.get_daily_perf(c, options[:range], options[:ext_options], perf_cols)
        if perf_cols.nil? || compute_perf.present?
          ts = compute_perf.last.timestamp if compute_perf
          [:cpu, :vcpus, :memory].each do |type|
            next if vm_needs[type].nil? || options[:target_options][type].nil?
            if type == :vcpus && vm_needs[type] > c.total_vcpus
              count_hash[type] = {:total => 0}
              next
            end
            avail, usage = offers(compute_perf, ts, options[:target_options][type], type, c)
            count_hash[type] = {:total => can_fit(avail, usage, vm_needs[type])}
          end
          unless vm_needs[:storage].nil? || options[:target_options][:storage].nil?
            details = []
            total   = 0
            type    = :storage
            storages_for_compute_target(c).each do |s|
              avail, usage = offers(compute_perf, ts, options[:target_options][type], type, s)
              fits = can_fit(avail, usage, vm_needs[type])
              details << {s.id => fits}
              total += fits unless fits.nil?
            end
            count_hash[type] = {:total => total, :details => details}
          end
        end
        count_hash[:total] = {:total => count_hash.each_value.pluck(:total).compact.max}
        {:target => c, :count => count_hash}
      end
      result = how_many_more_can_fit_host_to_cluster_results(result) if @compute.first.kind_of?(EmsCluster)
      return result, vm_needs
    end
def vm_how_many_more_can_fit ( options = { } ) options ||= @options vm_needs = get_vm_needs result = [ ] return result , vm_needs if @compute . blank? if @compute . first . kind_of? ( EmsCluster ) @hosts_to_cluster = { } MiqPreloader . preload ( @compute , :hosts => [ :hardware , { :vms => :hardware } ] ) compute_hosts = @compute . collect do | c | c . hosts . each { | h | @hosts_to_cluster [ h . id ] = c } c . hosts end . flatten else MiqPreloader . preload ( @compute , [ :hardware , { :vms => :hardware } ] ) compute_hosts = @compute end if VimPerformanceAnalysis . needs_perf_data? ( options [ :target_options ] ) perf_cols = [ :cpu , :vcpus , :memory , :storage ] . collect do | t | [ options [ :target_options ] . fetch_path ( t , :metric ) , options [ :target_options ] . fetch_path ( t , :limit_col ) ] end . flatten . compact end result = compute_hosts . collect do | c | count_hash = { } compute_perf = VimPerformanceAnalysis . get_daily_perf ( c , options [ :range ] , options [ :ext_options ] , perf_cols ) if perf_cols . nil? || compute_perf . present? ts = compute_perf . last . timestamp if compute_perf [ :cpu , :vcpus , :memory ] . each do | type | next if vm_needs [ type ] . nil? || options [ :target_options ] [ type ] . nil? if type == :vcpus && vm_needs [ type ] > c . total_vcpus count_hash [ type ] = { :total => 0 } next end avail , usage = offers ( compute_perf , ts , options [ :target_options ] [ type ] , type , c ) count_hash [ type ] = { :total => can_fit ( avail , usage , vm_needs [ type ] ) } end unless vm_needs [ :storage ] . nil? || options [ :target_options ] [ :storage ] . nil? details = [ ] total = 0 type = :storage storages_for_compute_target ( c ) . each do | s | avail , usage = offers ( compute_perf , ts , options [ :target_options ] [ type ] , type , s ) fits = can_fit ( avail , usage , vm_needs [ type ] ) details << { s . id => fits } total += fits unless fits . nil? end count_hash [ type ] = { :total => total , :details => details } end end count_hash [ :total ] = { :total => count_hash . each_value . pluck ( :total ) . compact . max } { :target => c , :count => count_hash } end result = how_many_more_can_fit_host_to_cluster_results ( result ) if @compute . first . kind_of? ( EmsCluster ) return result , vm_needs end
This method answers C&U Planning question 2
This method answers C&U Planning question 2
# For clusters, to allow for fragmentation in calculations, calculate using child hosts and aggregate at the end. # if we rely upon daily perf columns, make sure we have values for them # Returns an array of hashes # [{:target => Host/Cluster Object, :count => {:total   => {:total => Overall number of instances of provided VM that will fit in the target}, #                                              :cpu     => {:total => Count based on CPU}, #                                              :memory  => {:total => Count based on memory}, #                                              :storage => {:total => Count based on storage, :details => [{<storage.id> => Count for this storage}, ...], # ...]
options
<not_specific>