// 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 }
// The method veryfies whether resources should be set for the given pod and // if there is estimation available the method fills Request field. func (ir initialResources) estimateAndFillResourcesIfNotSet(pod *api.Pod) { annotations := []string{} for i := range pod.Spec.Containers { c := &pod.Spec.Containers[i] req := c.Resources.Requests lim := c.Resources.Limits var cpu, mem *resource.Quantity var err error if _, ok := req[api.ResourceCPU]; !ok { if _, ok2 := lim[api.ResourceCPU]; !ok2 { cpu, err = ir.getEstimation(api.ResourceCPU, c, pod.ObjectMeta.Namespace) if err != nil { glog.Errorf("Error while trying to estimate resources: %v", err) } } } if _, ok := req[api.ResourceMemory]; !ok { if _, ok2 := lim[api.ResourceMemory]; !ok2 { mem, err = ir.getEstimation(api.ResourceMemory, c, pod.ObjectMeta.Namespace) if err != nil { glog.Errorf("Error while trying to estimate resources: %v", err) } } } // If Requests doesn't exits and an estimation was made, create Requests. if req == nil && (cpu != nil || mem != nil) { c.Resources.Requests = api.ResourceList{} req = c.Resources.Requests } setRes := []string{} if cpu != nil { glog.Infof("CPU estimation for container %v in pod %v/%v is %v", c.Name, pod.ObjectMeta.Namespace, pod.ObjectMeta.Name, cpu.String()) setRes = append(setRes, string(api.ResourceCPU)) req[api.ResourceCPU] = *cpu } if mem != nil { glog.Infof("Memory estimation for container %v in pod %v/%v is %v", c.Name, pod.ObjectMeta.Namespace, pod.ObjectMeta.Name, mem.String()) setRes = append(setRes, string(api.ResourceMemory)) req[api.ResourceMemory] = *mem } if len(setRes) > 0 { a := strings.Join(setRes, ", ") + " request for container " + c.Name annotations = append(annotations, a) } } if len(annotations) > 0 { if pod.ObjectMeta.Annotations == nil { pod.ObjectMeta.Annotations = make(map[string]string) } val := "Initial Resources plugin set: " + strings.Join(annotations, "; ") pod.ObjectMeta.Annotations[initialResourcesAnnotation] = val } }
// maxConstraint enforces the max constraint over the specified resource func maxConstraint(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, enforcedValue := requestLimitEnforcedValues(req, lim, enforced) if !limExists { return fmt.Errorf("Maximum %s usage per %s is %s. No limit is specified.", resourceName, limitType, enforced.String()) } if observedLimValue > enforcedValue { return fmt.Errorf("Maximum %s usage per %s is %s, but limit is %s.", resourceName, limitType, enforced.String(), lim.String()) } if reqExists && (observedReqValue > enforcedValue) { return fmt.Errorf("Maximum %s usage per %s is %s, but request is %s.", resourceName, limitType, enforced.String(), req.String()) } return nil }