Skip to content

Commit a13c1d8

Browse files
authored
adding oldest_create_index (#961)
1 parent e78d490 commit a13c1d8

File tree

5 files changed

+113
-5
lines changed

5 files changed

+113
-5
lines changed

CHANGELOG.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,23 @@
33
BUG FIXES:
44
* config: Fixed a bug where the Nomad strategy and target plugins would fail to connect to Nomad's Task API socket [[GH-966](https://github.com/hashicorp/nomad-autoscaler/pull/966)]
55

6+
IMPROVEMENTS:
7+
* scaleutils: Add new node selector option `oldest_create_index` to select nodes with the oldest creation date [[GH-961](https://github.com/hashicorp/nomad-autoscaler/pull/961)]
8+
69
## 0.4.5 (August 13, 2024)
710

811
IMPROVEMENTS:
9-
* build: Updated to Go 1.22.6 and alpine to 3.20 [[GH-943](https://github.com/hashicorp/nomad-autoscaler/pull/943)]
10-
* build: Updated Nomad API dependency to 1.8.3 [[GH-950](https://github.com/hashicorp/nomad-autoscaler/pull/950)]
12+
* build: Updated to Go 1.22.6 and alpine to 3.20 [[GH-943](https://github.com/hashicorp/nomad-autoscaler/pull/943)]
13+
* build: Updated Nomad API dependency to 1.8.3 [[GH-950](https://github.com/hashicorp/nomad-autoscaler/pull/950)]
1114

1215
BUG FIXES:
13-
* security: Fix incorrect conversion between integer types [[GH-946](https://github.com/hashicorp/nomad-autoscaler/pull/946)]
16+
* security: Fix incorrect conversion between integer types [[GH-946](https://github.com/hashicorp/nomad-autoscaler/pull/946)]
1417

1518
## 0.4.4 (June 4, 2024)
1619

1720
IMPROVEMENTS:
18-
* agent: Update Nomad API dependency to v1.8.0 [[GH-909](https://github.com/hashicorp/nomad-autoscaler/pull/909)]
19-
* plugin/strategy/pass-through: Add new configuration `max_scale_up` and `max_scale_down` to allow restricting how much change is applied on each scaling event [[GH-881](https://github.com/hashicorp/nomad-autoscaler/pull/881)]
21+
* agent: Update Nomad API dependency to v1.8.0 [[GH-909](https://github.com/hashicorp/nomad-autoscaler/pull/909)]
22+
* plugin/strategy/pass-through: Add new configuration `max_scale_up` and `max_scale_down` to allow restricting how much change is applied on each scaling event [[GH-881](https://github.com/hashicorp/nomad-autoscaler/pull/881)]
2023

2124
## 0.4.3 (March 12, 2024)
2225

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package nodeselector
5+
6+
import (
7+
"github.com/hashicorp/nomad-autoscaler/sdk"
8+
"github.com/hashicorp/nomad/api"
9+
)
10+
11+
// oldestCreateIndexClusterScaleInNodeSelector is the NodeSelector
12+
// implementation of the ClusterScaleInNodeSelector interface. It selects nodes
13+
// based off the list ordering from Nomad and is the default selector.
14+
type oldestCreateIndexClusterScaleInNodeSelector struct{}
15+
16+
// newoldestCreateIndexClusterScaleInNodeSelector returns a new
17+
// oldestCreateIndexClusterScaleInNodeSelector implementation of the
18+
// ClusterScaleInNodeSelector interface.
19+
func newOldestCreateIndexClusterScaleInNodeSelector() ClusterScaleInNodeSelector {
20+
return &oldestCreateIndexClusterScaleInNodeSelector{}
21+
}
22+
23+
// Name satisfies the Name function on the ClusterScaleInNodeSelector
24+
// interface.
25+
func (n *oldestCreateIndexClusterScaleInNodeSelector) Name() string {
26+
return sdk.TargetNodeSelectorStrategyOldestCreateIndex
27+
}
28+
29+
// Select satisfies the Select function on the ClusterScaleInNodeSelector
30+
// interface.
31+
func (n *oldestCreateIndexClusterScaleInNodeSelector) Select(nodes []*api.NodeListStub, num int) []*api.NodeListStub {
32+
33+
last_index := len(nodes) - 1
34+
if len(nodes) < num {
35+
num = len(nodes)
36+
}
37+
out := make([]*api.NodeListStub, num)
38+
39+
for i := num - 1; i >= 0; i-- {
40+
out[i] = nodes[(last_index)-i]
41+
}
42+
return out
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package nodeselector
5+
6+
import (
7+
"testing"
8+
9+
"github.com/hashicorp/nomad/api"
10+
"github.com/shoenig/test/must"
11+
)
12+
13+
func Test_oldestClusterScaleInNodeSelectorName(t *testing.T) {
14+
must.Eq(t, "oldest_create_index", newOldestCreateIndexClusterScaleInNodeSelector().Name())
15+
}
16+
17+
func Test_oldestClusterScaleInNodeSelector_Select(t *testing.T) {
18+
testCases := []struct {
19+
inputNodes []*api.NodeListStub
20+
inputNum int
21+
expectedOutput []*api.NodeListStub
22+
name string
23+
}{
24+
{
25+
inputNodes: []*api.NodeListStub{
26+
{ID: "8d01d8fe-3c6b-0fdd-ebbc-a8b5cbb9c00c"},
27+
{ID: "a6604683-fd65-c913-77ee-a0a15b8e88e9"},
28+
},
29+
inputNum: 1,
30+
expectedOutput: []*api.NodeListStub{
31+
{ID: "a6604683-fd65-c913-77ee-a0a15b8e88e9"},
32+
},
33+
name: "single selection needed",
34+
},
35+
36+
{
37+
inputNodes: []*api.NodeListStub{
38+
{ID: "8d01d8fe-3c6b-0fdd-ebbc-a8b5cbb9c00c"},
39+
{ID: "a6604683-fd65-c913-77ee-a0a15b8e88e9"},
40+
},
41+
inputNum: 3,
42+
expectedOutput: []*api.NodeListStub{
43+
{ID: "a6604683-fd65-c913-77ee-a0a15b8e88e9"},
44+
{ID: "8d01d8fe-3c6b-0fdd-ebbc-a8b5cbb9c00c"},
45+
},
46+
name: "multiple selection",
47+
},
48+
}
49+
50+
for _, tc := range testCases {
51+
t.Run(tc.name, func(t *testing.T) {
52+
actualOutput := newOldestCreateIndexClusterScaleInNodeSelector().Select(tc.inputNodes, tc.inputNum)
53+
must.Eq(t, tc.expectedOutput, actualOutput)
54+
})
55+
}
56+
}

sdk/helper/scaleutils/nodeselector/selector.go

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ func NewSelector(cfg map[string]string, client *api.Client, log hclog.Logger) (C
4949
return newEmptyClusterScaleInNodeSelector(client, log, false), nil
5050
case sdk.TargetNodeSelectorStrategyEmptyIgnoreSystemJobs:
5151
return newEmptyClusterScaleInNodeSelector(client, log, true), nil
52+
case sdk.TargetNodeSelectorStrategyOldestCreateIndex:
53+
return newOldestCreateIndexClusterScaleInNodeSelector(), nil
5254
default:
5355
return nil, fmt.Errorf("unsupported node selector strategy: %v", val)
5456
}

sdk/target.go

+4
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ const (
124124
// node selection strategy that only picks nodes without non-terminal
125125
// allocations, without considering system jobs.
126126
TargetNodeSelectorStrategyEmptyIgnoreSystemJobs = "empty_ignore_system"
127+
128+
// TargetNodeSelectorStrategyEmptyIgnoreSystemJobs is the cluster scale-in
129+
// node selection strategy that picks the oldest running nodes
130+
TargetNodeSelectorStrategyOldestCreateIndex = "oldest_create_index"
127131
)
128132

129133
// TargetConfigConflictingClusterParams is a list containing horizontal cluster

0 commit comments

Comments
 (0)