Skip to content

Commit 79ab958

Browse files
committed
Revert assumed PVs and PVCs in unreserve extension point
1 parent bb11561 commit 79ab958

File tree

4 files changed

+47
-5
lines changed

4 files changed

+47
-5
lines changed

pkg/controller/volume/scheduling/scheduler_binder.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ type SchedulerVolumeBinder interface {
118118
// This function is called serially.
119119
AssumePodVolumes(assumedPod *v1.Pod, nodeName string) (allFullyBound bool, err error)
120120

121+
// RevertAssumedPodVolumes will revert assumed PV and PVC cache.
122+
RevertAssumedPodVolumes(assumedPod *v1.Pod, nodeName string)
123+
121124
// BindPodVolumes will:
122125
// 1. Initiate the volume binding by making the API call to prebind the PV
123126
// to its matching PVC.
@@ -387,6 +390,12 @@ func (b *volumeBinder) AssumePodVolumes(assumedPod *v1.Pod, nodeName string) (al
387390
return
388391
}
389392

393+
// RevertAssumedPodVolumes will revert assumed PV and PVC cache.
394+
func (b *volumeBinder) RevertAssumedPodVolumes(assumedPod *v1.Pod, nodeName string) {
395+
b.revertAssumedPVs(b.podBindingCache.GetBindings(assumedPod, nodeName))
396+
b.revertAssumedPVCs(b.podBindingCache.GetProvisionedPVCs(assumedPod, nodeName))
397+
}
398+
390399
// BindPodVolumes gets the cached bindings and PVCs to provision in podBindingCache,
391400
// makes the API update for those PVs/PVCs, and waits for the PVCs to be completely bound
392401
// by the PV controller.

pkg/controller/volume/scheduling/scheduler_binder_fake.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ func (b *FakeVolumeBinder) AssumePodVolumes(assumedPod *v1.Pod, nodeName string)
5353
return b.config.AllBound, b.config.AssumeErr
5454
}
5555

56+
// RevertAssumedPodVolumes implements SchedulerVolumeBinder.RevertAssumedPodVolumes
57+
func (b *FakeVolumeBinder) RevertAssumedPodVolumes(assumedPod *v1.Pod, nodeName string) {}
58+
5659
// BindPodVolumes implements SchedulerVolumeBinder.BindPodVolumes.
5760
func (b *FakeVolumeBinder) BindPodVolumes(assumedPod *v1.Pod) error {
5861
b.BindCalled = true

pkg/controller/volume/scheduling/scheduler_binder_test.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,13 +465,14 @@ func (env *testEnv) validateAssume(t *testing.T, pod *v1.Pod, bindings []*bindin
465465
}
466466
}
467467

468-
func (env *testEnv) validateFailedAssume(t *testing.T, pod *v1.Pod, bindings []*bindingInfo, provisionings []*v1.PersistentVolumeClaim) {
468+
func (env *testEnv) validateCacheRestored(t *testing.T, pod *v1.Pod, bindings []*bindingInfo, provisionings []*v1.PersistentVolumeClaim) {
469469
// All PVs have been unmodified in cache
470470
pvCache := env.internalBinder.pvCache
471471
for _, b := range bindings {
472472
pv, _ := pvCache.GetPV(b.pv.Name)
473+
apiPV, _ := pvCache.GetAPIPV(b.pv.Name)
473474
// PV could be nil if it's missing from cache
474-
if pv != nil && pv != b.pv {
475+
if pv != nil && pv != apiPV {
475476
t.Errorf("PV %q was modified in cache", b.pv.Name)
476477
}
477478
}
@@ -1225,7 +1226,7 @@ func TestAssumePodVolumes(t *testing.T) {
12251226
scenario.expectedProvisionings = scenario.provisionedPVCs
12261227
}
12271228
if scenario.shouldFail {
1228-
testEnv.validateFailedAssume(t, pod, scenario.expectedBindings, scenario.expectedProvisionings)
1229+
testEnv.validateCacheRestored(t, pod, scenario.bindings, scenario.provisionedPVCs)
12291230
} else {
12301231
testEnv.validateAssume(t, pod, scenario.expectedBindings, scenario.expectedProvisionings)
12311232
}
@@ -1237,6 +1238,34 @@ func TestAssumePodVolumes(t *testing.T) {
12371238
}
12381239
}
12391240

1241+
func TestRevertAssumedPodVolumes(t *testing.T) {
1242+
ctx, cancel := context.WithCancel(context.Background())
1243+
defer cancel()
1244+
1245+
podPVCs := []*v1.PersistentVolumeClaim{unboundPVC, provisionedPVC}
1246+
bindings := []*bindingInfo{makeBinding(unboundPVC, pvNode1a)}
1247+
pvs := []*v1.PersistentVolume{pvNode1a}
1248+
provisionedPVCs := []*v1.PersistentVolumeClaim{provisionedPVC}
1249+
expectedBindings := []*bindingInfo{makeBinding(unboundPVC, pvNode1aBound)}
1250+
expectedProvisionings := []*v1.PersistentVolumeClaim{selectedNodePVC}
1251+
1252+
// Setup
1253+
testEnv := newTestBinder(t, ctx.Done())
1254+
testEnv.initClaims(podPVCs, podPVCs)
1255+
pod := makePod(podPVCs)
1256+
testEnv.initPodCache(pod, "node1", bindings, provisionedPVCs)
1257+
testEnv.initVolumes(pvs, pvs)
1258+
1259+
allbound, err := testEnv.binder.AssumePodVolumes(pod, "node1")
1260+
if allbound || err != nil {
1261+
t.Errorf("No volumes are assumed")
1262+
}
1263+
testEnv.validateAssume(t, pod, expectedBindings, expectedProvisionings)
1264+
1265+
testEnv.binder.RevertAssumedPodVolumes(pod, "node1")
1266+
testEnv.validateCacheRestored(t, pod, bindings, provisionedPVCs)
1267+
}
1268+
12401269
func TestBindAPIUpdate(t *testing.T) {
12411270
type scenarioType struct {
12421271
// Inputs

pkg/scheduler/framework/plugins/volumebinding/volume_binding.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,10 @@ func (pl *VolumeBinding) PreBind(ctx context.Context, cs *framework.CycleState,
157157
return nil
158158
}
159159

160-
// Unreserve clears pod binding state.
161-
// TODO(#90962) Revert assumed PV/PVC cache
160+
// Unreserve clears assumed PV and PVC cache and pod binding state.
161+
// It's idempotent, and does nothing if no cache or binding state found for the given pod.
162162
func (pl *VolumeBinding) Unreserve(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) {
163+
pl.Binder.RevertAssumedPodVolumes(pod, nodeName)
163164
pl.Binder.DeletePodBindings(pod)
164165
return
165166
}

0 commit comments

Comments
 (0)