func printSingleResourceUsage(out io.Writer, resourceType api.ResourceName, quantity resource.Quantity) { switch resourceType { case api.ResourceCPU: fmt.Fprintf(out, "%vm", quantity.MilliValue()) case api.ResourceMemory: fmt.Fprintf(out, "%vMi", quantity.Value()/(1024*1024)) default: fmt.Fprintf(out, "%v", quantity.Value()) } }
// limitRequestRatioConstraint enforces the limit to request ratio over the specified resource func limitRequestRatioConstraint(limitType api.LimitType, resourceName api.ResourceName, enforced resource.Quantity, request api.ResourceList, limit api.ResourceList) error { req, reqExists := request[resourceName] lim, limExists := limit[resourceName] observedReqValue, observedLimValue, _ := requestLimitEnforcedValues(req, lim, enforced) if !reqExists || (observedReqValue == int64(0)) { return fmt.Errorf("%s max limit to request ratio per %s is %s, but no request is specified or request is 0.", resourceName, limitType, enforced.String()) } if !limExists || (observedLimValue == int64(0)) { return fmt.Errorf("%s max limit to request ratio per %s is %s, but no limit is specified or limit is 0.", resourceName, limitType, enforced.String()) } observedRatio := float64(observedLimValue) / float64(observedReqValue) displayObservedRatio := observedRatio maxLimitRequestRatio := float64(enforced.Value()) if enforced.Value() <= resource.MaxMilliValue { observedRatio = observedRatio * 1000 maxLimitRequestRatio = float64(enforced.MilliValue()) } if observedRatio > maxLimitRequestRatio { return fmt.Errorf("%s max limit to request ratio per %s is %s, but provided ratio is %f.", resourceName, limitType, enforced.String(), displayObservedRatio) } return nil }
// Calculates score for all pods and returns podInfo structure. // Score is defined as cpu_sum/node_capacity + mem_sum/node_capacity. // Pods that have bigger requirements should be processed first, thus have higher scores. func calculatePodScore(pods []*apiv1.Pod, nodeTemplate *schedulercache.NodeInfo) []*podInfo { podInfos := make([]*podInfo, 0, len(pods)) for _, pod := range pods { cpuSum := resource.Quantity{} memorySum := resource.Quantity{} for _, container := range pod.Spec.Containers { if request, ok := container.Resources.Requests[apiv1.ResourceCPU]; ok { cpuSum.Add(request) } if request, ok := container.Resources.Requests[apiv1.ResourceMemory]; ok { memorySum.Add(request) } } score := float64(0) if cpuAllocatable, ok := nodeTemplate.Node().Status.Allocatable[apiv1.ResourceCPU]; ok && cpuAllocatable.MilliValue() > 0 { score += float64(cpuSum.MilliValue()) / float64(cpuAllocatable.MilliValue()) } if memAllocatable, ok := nodeTemplate.Node().Status.Allocatable[apiv1.ResourceMemory]; ok && memAllocatable.Value() > 0 { score += float64(memorySum.Value()) / float64(memAllocatable.Value()) } podInfos = append(podInfos, &podInfo{ score: score, pod: pod, }) } return podInfos }
func addCpuLimit(opts []*unit.UnitOption, limit *resource.Quantity) ([]*unit.UnitOption, error) { if limit.Value() > resource.MaxMilliValue { return nil, fmt.Errorf("cpu limit exceeds the maximum millivalue: %v", limit.String()) } quota := strconv.Itoa(int(limit.MilliValue()/10)) + "%" opts = append(opts, unit.NewUnitOption("Service", "CPUQuota", quota)) return opts, nil }
// ValidateResourceQuantityValue enforces that specified quantity is valid for specified resource func ValidateResourceQuantityValue(resource string, value resource.Quantity, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, ValidateNonnegativeQuantity(value, fldPath)...) if api.IsIntegerResourceName(resource) { if value.MilliValue()%int64(1000) != int64(0) { allErrs = append(allErrs, field.Invalid(fldPath, value, isNotIntegerErrorMsg)) } } return allErrs }
func printSingleResourceUsage(out io.Writer, resourceType v1.ResourceName, quantity resource.Quantity) { switch resourceType { case v1.ResourceCPU: fmt.Fprintf(out, "%vm", quantity.MilliValue()) case v1.ResourceMemory: fmt.Fprintf(out, "%vMi", quantity.Value()/(1024*1024)) case v1.ResourceStorage: // TODO: Change it after storage metrics collection is finished. fmt.Fprint(out, "-") default: fmt.Fprintf(out, "%v", quantity.Value()) } }
// requestLimitEnforcedValues returns the specified values at a common precision to support comparability func requestLimitEnforcedValues(requestQuantity, limitQuantity, enforcedQuantity resource.Quantity) (request, limit, enforced int64) { request = requestQuantity.Value() limit = limitQuantity.Value() enforced = enforcedQuantity.Value() // do a more precise comparison if possible (if the value won't overflow) if request <= resource.MaxMilliValue && limit <= resource.MaxMilliValue && enforced <= resource.MaxMilliValue { request = requestQuantity.MilliValue() limit = limitQuantity.MilliValue() enforced = enforcedQuantity.MilliValue() } return }
// convertResourceCPUTOString converts cpu value to the format of divisor and returns // ceiling of the value. func convertResourceCPUToString(cpu *resource.Quantity, divisor resource.Quantity) (string, error) { c := int64(math.Ceil(float64(cpu.MilliValue()) / float64(divisor.MilliValue()))) return strconv.FormatInt(c, 10), nil }
func NewCPUShares(q resource.Quantity) CPUShares { return CPUShares(float64(q.MilliValue()) / 1000.0) }