in pkg/controllers/provisioning/binpacking/packer.go [85:140]
func (p *Packer) Pack(ctx context.Context, constraints *v1alpha5.Constraints, pods []*v1.Pod, instanceTypes []cloudprovider.InstanceType) ([]*Packing, error) {
defer metrics.Measure(packDuration.WithLabelValues(injection.GetNamespacedName(ctx).Name))()
// Get daemons for overhead calculations
daemons, err := p.getDaemons(ctx, constraints)
if err != nil {
return nil, fmt.Errorf("getting schedulable daemon pods, %w", err)
}
// Sort pods in decreasing order by the amount of CPU requested, if
// CPU requested is equal compare memory requested.
sort.Slice(pods, func(a, b int) bool {
resourcePodA := resources.RequestsForPods(pods[a])
resourcePodB := resources.RequestsForPods(pods[b])
if resourcePodA.Cpu().Equal(*resourcePodB.Cpu()) {
// check for memory
return resourcePodA.Memory().Cmp(*resourcePodB.Memory()) == 1
}
return resourcePodA.Cpu().Cmp(*resourcePodB.Cpu()) == 1
})
packs := map[uint64]*Packing{}
var packings []*Packing
var packing *Packing
remainingPods := pods
emptyPackables := PackablesFor(ctx, instanceTypes, constraints, pods, daemons)
for len(remainingPods) > 0 {
packables := []*Packable{}
for _, packable := range emptyPackables {
packables = append(packables, packable.DeepCopy())
}
if len(packables) == 0 {
logging.FromContext(ctx).Errorf("Failed to find instance type option(s) for %v", apiobject.PodNamespacedNames(remainingPods))
return packings, nil
}
packing, remainingPods = p.packWithLargestPod(remainingPods, packables)
// checked all instance types and found no packing option
if flattenedLen(packing.Pods...) == 0 {
logging.FromContext(ctx).Errorf("Failed to compute packing, pod(s) %s did not fit in instance type option(s) %v", apiobject.PodNamespacedNames(remainingPods), packableNames(packables))
remainingPods = remainingPods[1:]
continue
}
key, err := hashstructure.Hash(packing, hashstructure.FormatV2, &hashstructure.HashOptions{SlicesAsSets: true})
if err != nil {
return nil, fmt.Errorf("hashing packings, %w", err)
}
if mainPack, ok := packs[key]; ok {
mainPack.NodeQuantity++
mainPack.Pods = append(mainPack.Pods, packing.Pods...)
continue
}
packs[key] = packing
packings = append(packings, packing)
}
for _, pack := range packings {
logging.FromContext(ctx).Infof("Computed packing of %d node(s) for %d pod(s) with instance type option(s) %s", pack.NodeQuantity, flattenedLen(pack.Pods...), instanceTypeNames(pack.InstanceTypeOptions))
}
return packings, nil
}