Skip to content

Commit 2854870

Browse files
committed
Allow simulator to persist changes in cluster snapshot
1 parent 6419abf commit 2854870

File tree

3 files changed

+29
-15
lines changed

3 files changed

+29
-15
lines changed

cluster-autoscaler/core/scaledown/legacy/legacy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ type ScaleDown struct {
6565
// NewScaleDown builds new ScaleDown object.
6666
func NewScaleDown(context *context.AutoscalingContext, processors *processors.AutoscalingProcessors, clusterStateRegistry *clusterstate.ClusterStateRegistry, ndt *deletiontracker.NodeDeletionTracker) *ScaleDown {
6767
usageTracker := simulator.NewUsageTracker()
68-
removalSimulator := simulator.NewRemovalSimulator(context.ListerRegistry, context.ClusterSnapshot, context.PredicateChecker, usageTracker)
68+
removalSimulator := simulator.NewRemovalSimulator(context.ListerRegistry, context.ClusterSnapshot, context.PredicateChecker, usageTracker, false)
6969
unremovableNodes := unremovable.NewNodes()
7070
return &ScaleDown{
7171
context: context,

cluster-autoscaler/simulator/cluster.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,17 @@ type RemovalSimulator struct {
101101
clusterSnapshot ClusterSnapshot
102102
predicateChecker PredicateChecker
103103
usageTracker *UsageTracker
104+
canPersist bool
104105
}
105106

106107
// NewRemovalSimulator returns a new RemovalSimulator.
107-
func NewRemovalSimulator(listers kube_util.ListerRegistry, clusterSnapshot ClusterSnapshot, predicateChecker PredicateChecker, usageTracker *UsageTracker) *RemovalSimulator {
108+
func NewRemovalSimulator(listers kube_util.ListerRegistry, clusterSnapshot ClusterSnapshot, predicateChecker PredicateChecker, usageTracker *UsageTracker, persistSuccessfulSimulations bool) *RemovalSimulator {
108109
return &RemovalSimulator{
109110
listers: listers,
110111
clusterSnapshot: clusterSnapshot,
111112
predicateChecker: predicateChecker,
112113
usageTracker: usageTracker,
114+
canPersist: persistSuccessfulSimulations,
113115
}
114116
}
115117

@@ -174,7 +176,9 @@ func (r *RemovalSimulator) CheckNodeRemoval(
174176
return nil, &UnremovableNode{Node: nodeInfo.Node(), Reason: UnexpectedError}
175177
}
176178

177-
err = r.findPlaceFor(nodeName, podsToRemove, destinationMap, oldHints, newHints, timestamp)
179+
err = r.withForkedSnapshot(func() error {
180+
return r.findPlaceFor(nodeName, podsToRemove, destinationMap, oldHints, newHints, timestamp)
181+
})
178182
if err != nil {
179183
klog.V(2).Infof("node %s is not suitable for removal: %v", nodeName, err)
180184
return nil, &UnremovableNode{Node: nodeInfo.Node(), Reason: NoPlaceToMovePods}
@@ -205,19 +209,29 @@ func (r *RemovalSimulator) FindEmptyNodesToRemove(candidates []string, timestamp
205209
return result
206210
}
207211

208-
func (r *RemovalSimulator) findPlaceFor(removedNode string, pods []*apiv1.Pod, nodes map[string]bool,
209-
oldHints map[string]string, newHints map[string]string, timestamp time.Time) error {
210-
211-
if err := r.clusterSnapshot.Fork(); err != nil {
212+
func (r *RemovalSimulator) withForkedSnapshot(f func() error) (err error) {
213+
if err = r.clusterSnapshot.Fork(); err != nil {
212214
return err
213215
}
214216
defer func() {
215-
err := r.clusterSnapshot.Revert()
216-
if err != nil {
217-
klog.Fatalf("Got error when calling ClusterSnapshot.Revert(); %v", err)
217+
if err == nil && r.canPersist {
218+
cleanupErr := r.clusterSnapshot.Commit()
219+
if cleanupErr != nil {
220+
klog.Fatalf("Got error when calling ClusterSnapshot.Commit(); %v", cleanupErr)
221+
}
222+
} else {
223+
cleanupErr := r.clusterSnapshot.Revert()
224+
if cleanupErr != nil {
225+
klog.Fatalf("Got error when calling ClusterSnapshot.Revert(); %v", cleanupErr)
226+
}
218227
}
219228
}()
229+
err = f()
230+
return err
231+
}
220232

233+
func (r *RemovalSimulator) findPlaceFor(removedNode string, pods []*apiv1.Pod, nodes map[string]bool,
234+
oldHints map[string]string, newHints map[string]string, timestamp time.Time) error {
221235
podKey := func(pod *apiv1.Pod) string {
222236
return fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
223237
}

cluster-autoscaler/simulator/cluster_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func TestFindPlaceAllOk(t *testing.T) {
5858
[]*apiv1.Node{node1, node2},
5959
[]*apiv1.Pod{pod1})
6060

61-
err = NewRemovalSimulator(nil, clusterSnapshot, predicateChecker, NewUsageTracker()).findPlaceFor(
61+
err = NewRemovalSimulator(nil, clusterSnapshot, predicateChecker, NewUsageTracker(), false).findPlaceFor(
6262
"x",
6363
[]*apiv1.Pod{new1, new2},
6464
destinations,
@@ -96,7 +96,7 @@ func TestFindPlaceAllBas(t *testing.T) {
9696
[]*apiv1.Node{node1, node2},
9797
[]*apiv1.Pod{pod1})
9898

99-
err = NewRemovalSimulator(nil, clusterSnapshot, predicateChecker, NewUsageTracker()).findPlaceFor(
99+
err = NewRemovalSimulator(nil, clusterSnapshot, predicateChecker, NewUsageTracker(), false).findPlaceFor(
100100
"nbad",
101101
[]*apiv1.Pod{new1, new2, new3},
102102
destinations,
@@ -129,7 +129,7 @@ func TestFindNone(t *testing.T) {
129129
[]*apiv1.Node{node1, node2},
130130
[]*apiv1.Pod{pod1})
131131

132-
err = NewRemovalSimulator(nil, clusterSnapshot, predicateChecker, NewUsageTracker()).findPlaceFor(
132+
err = NewRemovalSimulator(nil, clusterSnapshot, predicateChecker, NewUsageTracker(), false).findPlaceFor(
133133
"x",
134134
[]*apiv1.Pod{},
135135
destinations,
@@ -162,7 +162,7 @@ func TestFindEmptyNodes(t *testing.T) {
162162
clusterSnapshot := NewBasicClusterSnapshot()
163163
InitializeClusterSnapshotOrDie(t, clusterSnapshot, []*apiv1.Node{nodes[0], nodes[1], nodes[2], nodes[3]}, []*apiv1.Pod{pod1, pod2})
164164
testTime := time.Date(2020, time.December, 18, 17, 0, 0, 0, time.UTC)
165-
r := NewRemovalSimulator(nil, clusterSnapshot, nil, nil)
165+
r := NewRemovalSimulator(nil, clusterSnapshot, nil, nil, false)
166166
emptyNodes := r.FindEmptyNodesToRemove(nodeNames, testTime)
167167
assert.Equal(t, []string{nodeNames[0], nodeNames[2], nodeNames[3]}, emptyNodes)
168168
}
@@ -309,7 +309,7 @@ func TestFindNodesToRemove(t *testing.T) {
309309
destinations = append(destinations, node.Name)
310310
}
311311
InitializeClusterSnapshotOrDie(t, clusterSnapshot, test.allNodes, test.pods)
312-
r := NewRemovalSimulator(registry, clusterSnapshot, predicateChecker, tracker)
312+
r := NewRemovalSimulator(registry, clusterSnapshot, predicateChecker, tracker, false)
313313
toRemove, unremovable, _, err := r.FindNodesToRemove(
314314
test.candidates, destinations, map[string]string{},
315315
time.Now(), []*policyv1.PodDisruptionBudget{})

0 commit comments

Comments
 (0)