Skip to content

Commit c4fdf3d

Browse files
authored
Merge pull request kubernetes#109290 from gnufied/fix-inline-migrations-spec
Fix error for inline migrated volumes
2 parents 71cf2ea + 5da524d commit c4fdf3d

File tree

3 files changed

+115
-10
lines changed

3 files changed

+115
-10
lines changed

pkg/kubelet/volumemanager/populator/desired_state_of_world_populator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ func (dswp *desiredStateOfWorldPopulator) checkVolumeFSResize(
343343
volumeSpec *volume.Spec,
344344
uniquePodName volumetypes.UniquePodName,
345345
mountedVolumesForPod map[volumetypes.UniquePodName]map[string]cache.MountedVolume) {
346-
if podVolume.PersistentVolumeClaim == nil {
346+
if podVolume.PersistentVolumeClaim == nil || pvc == nil {
347347
// Only PVC supports resize operation.
348348
return
349349
}

pkg/kubelet/volumemanager/reconciler/reconciler_test.go

+113-8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package reconciler
1919
import (
2020
"crypto/md5"
2121
"fmt"
22+
csitrans "k8s.io/csi-translation-lib"
23+
"k8s.io/kubernetes/pkg/volume/csimigration"
2224
"testing"
2325
"time"
2426

@@ -177,6 +179,105 @@ func Test_Run_Positive_VolumeAttachAndMount(t *testing.T) {
177179
assert.NoError(t, volumetesting.VerifyZeroDetachCallCount(fakePlugin))
178180
}
179181

182+
// Populates desiredStateOfWorld cache with one volume/pod.
183+
// Calls Run()
184+
// Verifies there is are attach/mount/etc calls and no detach/unmount calls.
185+
func Test_Run_Positive_VolumeAttachAndMountMigrationEnabled(t *testing.T) {
186+
// Arrange
187+
intreeToCSITranslator := csitrans.New()
188+
node := &v1.Node{
189+
ObjectMeta: metav1.ObjectMeta{
190+
Name: string(nodeName),
191+
},
192+
Spec: v1.NodeSpec{},
193+
Status: v1.NodeStatus{
194+
VolumesAttached: []v1.AttachedVolume{
195+
{
196+
Name: v1.UniqueVolumeName(fmt.Sprintf("fake-plugin/%s", "pd.csi.storage.gke.io-fake-device1")),
197+
DevicePath: "fake/path",
198+
},
199+
},
200+
},
201+
}
202+
volumePluginMgr, fakePlugin := volumetesting.GetTestKubeletVolumePluginMgrWithNode(t, node)
203+
dsw := cache.NewDesiredStateOfWorld(volumePluginMgr)
204+
205+
asw := cache.NewActualStateOfWorld(nodeName, volumePluginMgr)
206+
kubeClient := createTestClient(v1.AttachedVolume{
207+
Name: v1.UniqueVolumeName(fmt.Sprintf("fake-plugin/%s", "pd.csi.storage.gke.io-fake-device1")),
208+
DevicePath: "fake/path",
209+
})
210+
211+
fakeRecorder := &record.FakeRecorder{}
212+
fakeHandler := volumetesting.NewBlockVolumePathHandler()
213+
oex := operationexecutor.NewOperationExecutor(operationexecutor.NewOperationGenerator(
214+
kubeClient,
215+
volumePluginMgr,
216+
fakeRecorder,
217+
fakeHandler))
218+
reconciler := NewReconciler(
219+
kubeClient,
220+
true, /* controllerAttachDetachEnabled */
221+
reconcilerLoopSleepDuration,
222+
waitForAttachTimeout,
223+
nodeName,
224+
dsw,
225+
asw,
226+
hasAddedPods,
227+
oex,
228+
mount.NewFakeMounter(nil),
229+
hostutil.NewFakeHostUtil(nil),
230+
volumePluginMgr,
231+
kubeletPodsDir)
232+
pod := &v1.Pod{
233+
ObjectMeta: metav1.ObjectMeta{
234+
Name: "pod1",
235+
UID: "pod1uid",
236+
},
237+
Spec: v1.PodSpec{
238+
Volumes: []v1.Volume{
239+
{
240+
Name: "volume-name",
241+
VolumeSource: v1.VolumeSource{
242+
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
243+
PDName: "fake-device1",
244+
},
245+
},
246+
},
247+
},
248+
},
249+
}
250+
251+
volumeSpec := &volume.Spec{Volume: &pod.Spec.Volumes[0]}
252+
migratedSpec, err := csimigration.TranslateInTreeSpecToCSI(volumeSpec, pod.Namespace, intreeToCSITranslator)
253+
if err != nil {
254+
t.Fatalf("unexpected error while translating spec %v: %v", volumeSpec, err)
255+
}
256+
257+
podName := util.GetUniquePodName(pod)
258+
generatedVolumeName, err := dsw.AddPodToVolume(
259+
podName, pod, migratedSpec, migratedSpec.Name(), "" /* volumeGidValue */)
260+
261+
// Assert
262+
if err != nil {
263+
t.Fatalf("AddPodToVolume failed. Expected: <no error> Actual: <%v>", err)
264+
}
265+
dsw.MarkVolumesReportedInUse([]v1.UniqueVolumeName{generatedVolumeName})
266+
267+
// Act
268+
runReconciler(reconciler)
269+
waitForMount(t, fakePlugin, generatedVolumeName, asw)
270+
// Assert
271+
assert.NoError(t, volumetesting.VerifyWaitForAttachCallCount(
272+
1 /* expectedWaitForAttachCallCount */, fakePlugin))
273+
assert.NoError(t, volumetesting.VerifyMountDeviceCallCount(
274+
1 /* expectedMountDeviceCallCount */, fakePlugin))
275+
assert.NoError(t, volumetesting.VerifySetUpCallCount(
276+
1 /* expectedSetUpCallCount */, fakePlugin))
277+
assert.NoError(t, volumetesting.VerifyZeroTearDownCallCount(fakePlugin))
278+
assert.NoError(t, volumetesting.VerifyZeroDetachCallCount(fakePlugin))
279+
}
280+
180281
// Populates desiredStateOfWorld cache with one volume/pod.
181282
// Enables controllerAttachDetachEnabled.
182283
// Calls Run()
@@ -1896,21 +1997,25 @@ func retryWithExponentialBackOff(initialDuration time.Duration, fn wait.Conditio
18961997
return wait.ExponentialBackoff(backoff, fn)
18971998
}
18981999

1899-
func createTestClient() *fake.Clientset {
2000+
func createTestClient(attachedVolumes ...v1.AttachedVolume) *fake.Clientset {
19002001
fakeClient := &fake.Clientset{}
2002+
if len(attachedVolumes) == 0 {
2003+
attachedVolumes = append(attachedVolumes, v1.AttachedVolume{
2004+
Name: "fake-plugin/fake-device1",
2005+
DevicePath: "fake/path",
2006+
})
2007+
}
19012008
fakeClient.AddReactor("get", "nodes",
19022009
func(action core.Action) (bool, runtime.Object, error) {
19032010
return true, &v1.Node{
19042011
ObjectMeta: metav1.ObjectMeta{Name: string(nodeName)},
19052012
Status: v1.NodeStatus{
1906-
VolumesAttached: []v1.AttachedVolume{
1907-
{
1908-
Name: "fake-plugin/fake-device1",
1909-
DevicePath: "/fake/path",
1910-
},
1911-
}},
2013+
VolumesAttached: attachedVolumes,
2014+
},
19122015
}, nil
1913-
})
2016+
},
2017+
)
2018+
19142019
fakeClient.AddReactor("*", "*", func(action core.Action) (bool, runtime.Object, error) {
19152020
return true, nil, fmt.Errorf("no reaction implemented for %s", action)
19162021
})

pkg/volume/util/operationexecutor/operation_generator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ func (og *operationGenerator) GenerateVerifyControllerAttachedVolumeFunc(
14851485
claimSize := actualStateOfWorld.GetClaimSize(volumeToMount.VolumeName)
14861486

14871487
// only fetch claimSize if it was not set previously
1488-
if volumeToMount.VolumeSpec.PersistentVolume != nil && claimSize == nil {
1488+
if volumeToMount.VolumeSpec.PersistentVolume != nil && claimSize == nil && !volumeToMount.VolumeSpec.InlineVolumeSpecForCSIMigration {
14891489
pv := volumeToMount.VolumeSpec.PersistentVolume
14901490
pvc, err := og.kubeClient.CoreV1().PersistentVolumeClaims(pv.Spec.ClaimRef.Namespace).Get(context.TODO(), pv.Spec.ClaimRef.Name, metav1.GetOptions{})
14911491
if err != nil {

0 commit comments

Comments
 (0)