Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 0562d8e

Browse files
authored
Merge pull request #92 from thestormforge/limit-request-ratio
Limit request ratio
2 parents 3544f9d + 79c0a07 commit 0562d8e

File tree

4 files changed

+31
-1
lines changed

4 files changed

+31
-1
lines changed

pkg/api/applications/v2/recommendation.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ type ContainerResources struct {
8484
TargetUtilization *ResourceList `json:"targetUtilization,omitempty"`
8585
Tolerance *ResourceList `json:"tolerance,omitempty"`
8686
Bounds *Bounds `json:"bounds,omitempty"`
87+
LimitRequestRatio *ResourceList `json:"limitRequestRatio,omitempty"`
8788
}
8889

8990
type Bounds struct {

pkg/api/numorstr.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ func FromInt64(val int64) NumberOrString {
3838

3939
// FromFloat64 returns the supplied value as a NumberOrString
4040
func FromFloat64(val float64) NumberOrString {
41-
return NumberOrString{NumVal: json.Number(strconv.FormatFloat(val, 'f', -1, 64))}
41+
s := strconv.FormatFloat(val, 'f', -1, 64)
42+
if math.IsInf(val, 0) || math.IsNaN(val) {
43+
return NumberOrString{StrVal: s, IsString: true}
44+
}
45+
return NumberOrString{NumVal: json.Number(s)}
4246
}
4347

4448
// FromNumber returns the supplied value as a NumberOrString
@@ -166,6 +170,9 @@ func (s *NumberOrString) Quantity() *big.Float {
166170
if v, ok := new(big.Float).SetString(strVal); ok {
167171
return v.Mul(v, big.NewFloat(op))
168172
}
173+
} else if x, err := strconv.ParseFloat(s.StrVal, 64); err == nil { // +Inf, etc.
174+
// We use `ParseFloat` instead of `s.Float64Value()` so we can explicitly check the error
175+
return big.NewFloat(x)
169176
}
170177

171178
return nil

pkg/api/numorstr_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package api
22

33
import (
44
"encoding/json"
5+
"math"
56
"math/big"
67
"testing"
78

@@ -167,6 +168,12 @@ func TestNumberOrString_Float64Value(t *testing.T) {
167168
value: FromString("1"),
168169
expected: 1.0,
169170
},
171+
172+
{
173+
desc: "infinity",
174+
value: FromValue("infinity"),
175+
expected: math.Inf(1),
176+
},
170177
}
171178
for _, tc := range cases {
172179
t.Run(tc.desc, func(t *testing.T) {
@@ -292,6 +299,9 @@ func TestNumberOrString_Quantity(t *testing.T) {
292299
{value: "1T", expected: 1000000000000},
293300
{value: "1P", expected: 1000000000000000},
294301
{value: "1E", expected: 1000000000000000000},
302+
303+
// These are out of spec
304+
{value: "+Inf", expected: math.Inf(1)},
295305
}
296306
for _, tc := range cases {
297307
t.Run(tc.value, func(t *testing.T) {

pkg/command/recommendation/options.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const (
3737
flagContainerResourcesRequestsMin = "min-request"
3838
flagContainerResourcesTargetUtilizationMax = "max-target-utilization"
3939
flagContainerResourcesTargetUtilizationMin = "min-target-utilization"
40+
flagContainerResourcesLimitRequestRatio = "limit-request-ratio"
4041
)
4142

4243
const (
@@ -68,6 +69,7 @@ type ContainerResourcesOptions struct {
6869
BoundsRequestsMin map[string]string
6970
BoundsTargetUtilizationMax map[string]int64
7071
BoundsTargetUtilizationMin map[string]int64
72+
LimitRequestRatio map[string]string
7173
}
7274

7375
func (opts *ContainerResourcesOptions) AddFlags(cmd *cobra.Command) {
@@ -81,9 +83,11 @@ func (opts *ContainerResourcesOptions) AddFlags(cmd *cobra.Command) {
8183
cmd.Flags().StringToStringVar(&opts.BoundsRequestsMin, flagContainerResourcesRequestsMin, opts.BoundsRequestsMin, "per-container resource min requests as `resource=quantity`; resource is one of: cpu|memory")
8284
cmd.Flags().StringToInt64Var(&opts.BoundsTargetUtilizationMax, flagContainerResourcesTargetUtilizationMax, opts.BoundsTargetUtilizationMax, "per-container resource max target utilization as `resource=quantity`; resource is one of: cpu")
8385
cmd.Flags().StringToInt64Var(&opts.BoundsTargetUtilizationMin, flagContainerResourcesTargetUtilizationMin, opts.BoundsTargetUtilizationMin, "per-container resource min target utilization as `resource=quantity`; resource is one of: cpu")
86+
cmd.Flags().StringToStringVar(&opts.LimitRequestRatio, flagContainerResourcesLimitRequestRatio, opts.LimitRequestRatio, "per-container limit:request ratio as `resource=quantity`; resource is one of: cpu|memory")
8487

8588
cmd.Flag(flagContainerResourcesInterval).Hidden = true
8689
cmd.Flag(flagContainerResourcesTargetUtilization).Hidden = true
90+
cmd.Flag(flagContainerResourcesLimitRequestRatio).Hidden = true
8791
}
8892

8993
func (opts *ContainerResourcesOptions) Apply(configuration *[]applications.Configuration) {
@@ -121,6 +125,14 @@ func (opts *ContainerResourcesOptions) Apply(configuration *[]applications.Confi
121125
lazyContainerResources().Tolerance = tolerance
122126
}
123127

128+
if size := len(opts.LimitRequestRatio); size > 0 {
129+
limitRequestRatio := &applications.ResourceList{}
130+
for k, v := range opts.LimitRequestRatio {
131+
limitRequestRatio.Set(strings.ToLower(k), api.FromValue(v))
132+
}
133+
lazyContainerResources().LimitRequestRatio = limitRequestRatio
134+
}
135+
124136
bounds := &applications.Bounds{}
125137
lazyLimits := func() *applications.BoundsRange {
126138
if bounds.Limits == nil {

0 commit comments

Comments
 (0)