csi-translation-lib: Support structured and contextual logging

This commit is contained in:
bells17 2023-09-14 03:25:06 +09:00
parent 8ba158c7f4
commit 1298c8a5fe
No known key found for this signature in database
GPG Key ID: C97AFA7A642B9A2B
36 changed files with 257 additions and 185 deletions

View File

@ -136,6 +136,7 @@ linters-settings: # please keep this alphabetized
contextual k8s.io/component-helpers/.* contextual k8s.io/component-helpers/.*
contextual k8s.io/cri-api/.* contextual k8s.io/cri-api/.*
contextual k8s.io/cri-client/.* contextual k8s.io/cri-client/.*
contextual k8s.io/csi-translation-lib/.*
contextual k8s.io/dynamic-resource-allocation/.* contextual k8s.io/dynamic-resource-allocation/.*
contextual k8s.io/endpointslice/.* contextual k8s.io/endpointslice/.*
contextual k8s.io/kms/.* contextual k8s.io/kms/.*

View File

@ -182,6 +182,7 @@ linters-settings: # please keep this alphabetized
contextual k8s.io/component-helpers/.* contextual k8s.io/component-helpers/.*
contextual k8s.io/cri-api/.* contextual k8s.io/cri-api/.*
contextual k8s.io/cri-client/.* contextual k8s.io/cri-client/.*
contextual k8s.io/csi-translation-lib/.*
contextual k8s.io/dynamic-resource-allocation/.* contextual k8s.io/dynamic-resource-allocation/.*
contextual k8s.io/endpointslice/.* contextual k8s.io/endpointslice/.*
contextual k8s.io/kms/.* contextual k8s.io/kms/.*

View File

@ -185,6 +185,7 @@ linters-settings: # please keep this alphabetized
contextual k8s.io/component-helpers/.* contextual k8s.io/component-helpers/.*
contextual k8s.io/cri-api/.* contextual k8s.io/cri-api/.*
contextual k8s.io/cri-client/.* contextual k8s.io/cri-client/.*
contextual k8s.io/csi-translation-lib/.*
contextual k8s.io/dynamic-resource-allocation/.* contextual k8s.io/dynamic-resource-allocation/.*
contextual k8s.io/endpointslice/.* contextual k8s.io/endpointslice/.*
contextual k8s.io/kms/.* contextual k8s.io/kms/.*

View File

@ -32,6 +32,7 @@ contextual k8s.io/client-go/tools/record/.*
contextual k8s.io/component-helpers/.* contextual k8s.io/component-helpers/.*
contextual k8s.io/cri-api/.* contextual k8s.io/cri-api/.*
contextual k8s.io/cri-client/.* contextual k8s.io/cri-client/.*
contextual k8s.io/csi-translation-lib/.*
contextual k8s.io/dynamic-resource-allocation/.* contextual k8s.io/dynamic-resource-allocation/.*
contextual k8s.io/endpointslice/.* contextual k8s.io/endpointslice/.*
contextual k8s.io/kms/.* contextual k8s.io/kms/.*

View File

@ -711,7 +711,7 @@ func (adc *attachDetachController) processVolumeAttachments(logger klog.Logger)
// PV is migrated and should be handled by the CSI plugin instead of the in-tree one // PV is migrated and should be handled by the CSI plugin instead of the in-tree one
plugin, _ = adc.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName) plugin, _ = adc.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
// podNamespace is not needed here for Azurefile as the volumeName generated will be the same with or without podNamespace // podNamespace is not needed here for Azurefile as the volumeName generated will be the same with or without podNamespace
volumeSpec, err = csimigration.TranslateInTreeSpecToCSI(volumeSpec, "" /* podNamespace */, adc.intreeToCSITranslator) volumeSpec, err = csimigration.TranslateInTreeSpecToCSI(logger, volumeSpec, "" /* podNamespace */, adc.intreeToCSITranslator)
if err != nil { if err != nil {
logger.Error(err, "Failed to translate intree volumeSpec to CSI volumeSpec for volume", "node", klog.KRef("", string(nodeName)), "inTreePluginName", inTreePluginName, "vaName", va.Name, "PV", klog.KRef("", *pvName)) logger.Error(err, "Failed to translate intree volumeSpec to CSI volumeSpec for volume", "node", klog.KRef("", string(nodeName)), "inTreePluginName", inTreePluginName, "vaName", va.Name, "PV", klog.KRef("", *pvName))
continue continue

View File

@ -81,7 +81,7 @@ func CreateVolumeSpec(logger klog.Logger, podVolume v1.Volume, pod *v1.Pod, node
err) err)
} }
volumeSpec, err = translateInTreeSpecToCSIIfNeeded(volumeSpec, nodeName, vpm, csiMigratedPluginManager, csiTranslator, pod.Namespace) volumeSpec, err = translateInTreeSpecToCSIIfNeeded(logger, volumeSpec, nodeName, vpm, csiMigratedPluginManager, csiTranslator, pod.Namespace)
if err != nil { if err != nil {
return nil, fmt.Errorf( return nil, fmt.Errorf(
"error performing CSI migration checks and translation for PVC %q/%q: %v", "error performing CSI migration checks and translation for PVC %q/%q: %v",
@ -100,7 +100,7 @@ func CreateVolumeSpec(logger klog.Logger, podVolume v1.Volume, pod *v1.Pod, node
clonedPodVolume := podVolume.DeepCopy() clonedPodVolume := podVolume.DeepCopy()
origspec := volume.NewSpecFromVolume(clonedPodVolume) origspec := volume.NewSpecFromVolume(clonedPodVolume)
spec, err := translateInTreeSpecToCSIIfNeeded(origspec, nodeName, vpm, csiMigratedPluginManager, csiTranslator, pod.Namespace) spec, err := translateInTreeSpecToCSIIfNeeded(logger, origspec, nodeName, vpm, csiMigratedPluginManager, csiTranslator, pod.Namespace)
if err != nil { if err != nil {
return nil, fmt.Errorf( return nil, fmt.Errorf(
"error performing CSI migration checks and translation for inline volume %q: %v", "error performing CSI migration checks and translation for inline volume %q: %v",
@ -241,7 +241,7 @@ func ProcessPodVolumes(logger klog.Logger, pod *v1.Pod, addVolumes bool, desired
return return
} }
func translateInTreeSpecToCSIIfNeeded(spec *volume.Spec, nodeName types.NodeName, vpm *volume.VolumePluginMgr, csiMigratedPluginManager csimigration.PluginManager, csiTranslator csimigration.InTreeToCSITranslator, podNamespace string) (*volume.Spec, error) { func translateInTreeSpecToCSIIfNeeded(logger klog.Logger, spec *volume.Spec, nodeName types.NodeName, vpm *volume.VolumePluginMgr, csiMigratedPluginManager csimigration.PluginManager, csiTranslator csimigration.InTreeToCSITranslator, podNamespace string) (*volume.Spec, error) {
translatedSpec := spec translatedSpec := spec
migratable, err := csiMigratedPluginManager.IsMigratable(spec) migratable, err := csiMigratedPluginManager.IsMigratable(spec)
if err != nil { if err != nil {
@ -256,7 +256,7 @@ func translateInTreeSpecToCSIIfNeeded(spec *volume.Spec, nodeName types.NodeName
return nil, err return nil, err
} }
if migratable && migrationSupportedOnNode { if migratable && migrationSupportedOnNode {
translatedSpec, err = csimigration.TranslateInTreeSpecToCSI(spec, podNamespace, csiTranslator) translatedSpec, err = csimigration.TranslateInTreeSpecToCSI(logger, spec, podNamespace, csiTranslator)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1648,7 +1648,7 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) {
kl.warnCgroupV1Usage() kl.warnCgroupV1Usage()
// Start volume manager // Start volume manager
go kl.volumeManager.Run(kl.sourcesReady, wait.NeverStop) go kl.volumeManager.Run(ctx, kl.sourcesReady)
if kl.kubeClient != nil { if kl.kubeClient != nil {
// Start two go-routines to update the status. // Start two go-routines to update the status.

View File

@ -2997,12 +2997,6 @@ func simulateVolumeInUseUpdate(
} }
} }
func runVolumeManager(kubelet *Kubelet) chan struct{} {
stopCh := make(chan struct{})
go kubelet.volumeManager.Run(kubelet.sourcesReady, stopCh)
return stopCh
}
// dirExists returns true if the path exists and represents a directory. // dirExists returns true if the path exists and represents a directory.
func dirExists(path string) bool { func dirExists(path string) bool {
s, err := os.Stat(path) s, err := os.Stat(path)

View File

@ -31,6 +31,7 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetest "k8s.io/kubernetes/pkg/volume/testing" volumetest "k8s.io/kubernetes/pkg/volume/testing"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/test/utils/ktesting"
) )
func TestListVolumesForPod(t *testing.T) { func TestListVolumesForPod(t *testing.T) {
@ -78,8 +79,9 @@ func TestListVolumesForPod(t *testing.T) {
}, },
}) })
stopCh := runVolumeManager(kubelet) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
go kubelet.volumeManager.Run(tCtx, kubelet.sourcesReady)
kubelet.podManager.SetPods([]*v1.Pod{pod}) kubelet.podManager.SetPods([]*v1.Pod{pod})
err := kubelet.volumeManager.WaitForAttachAndMount(context.Background(), pod) err := kubelet.volumeManager.WaitForAttachAndMount(context.Background(), pod)
@ -196,8 +198,9 @@ func TestPodVolumesExist(t *testing.T) {
}, },
} }
stopCh := runVolumeManager(kubelet) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
go kubelet.volumeManager.Run(tCtx, kubelet.sourcesReady)
kubelet.podManager.SetPods(pods) kubelet.podManager.SetPods(pods)
for _, pod := range pods { for _, pod := range pods {
@ -255,8 +258,9 @@ func TestPodVolumeDeadlineAttachAndMount(t *testing.T) {
}, },
} }
stopCh := runVolumeManager(kubelet) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
go kubelet.volumeManager.Run(tCtx, kubelet.sourcesReady)
kubelet.podManager.SetPods(pods) kubelet.podManager.SetPods(pods)
for _, pod := range pods { for _, pod := range pods {
@ -316,8 +320,9 @@ func TestPodVolumeDeadlineUnmount(t *testing.T) {
}, },
} }
stopCh := runVolumeManager(kubelet) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
go kubelet.volumeManager.Run(tCtx, kubelet.sourcesReady)
kubelet.podManager.SetPods(pods) kubelet.podManager.SetPods(pods)
for i, pod := range pods { for i, pod := range pods {
@ -369,8 +374,9 @@ func TestVolumeAttachAndMountControllerDisabled(t *testing.T) {
}, },
}) })
stopCh := runVolumeManager(kubelet) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
go kubelet.volumeManager.Run(tCtx, kubelet.sourcesReady)
kubelet.podManager.SetPods([]*v1.Pod{pod}) kubelet.podManager.SetPods([]*v1.Pod{pod})
err := kubelet.volumeManager.WaitForAttachAndMount(context.Background(), pod) err := kubelet.volumeManager.WaitForAttachAndMount(context.Background(), pod)
@ -428,8 +434,9 @@ func TestVolumeUnmountAndDetachControllerDisabled(t *testing.T) {
}, },
}) })
stopCh := runVolumeManager(kubelet) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
go kubelet.volumeManager.Run(tCtx, kubelet.sourcesReady)
// Add pod // Add pod
kubelet.podManager.SetPods([]*v1.Pod{pod}) kubelet.podManager.SetPods([]*v1.Pod{pod})
@ -534,15 +541,16 @@ func TestVolumeAttachAndMountControllerEnabled(t *testing.T) {
}, },
}) })
stopCh := runVolumeManager(kubelet) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
go kubelet.volumeManager.Run(tCtx, kubelet.sourcesReady)
kubelet.podManager.SetPods([]*v1.Pod{pod}) kubelet.podManager.SetPods([]*v1.Pod{pod})
// Fake node status update // Fake node status update
go simulateVolumeInUseUpdate( go simulateVolumeInUseUpdate(
v1.UniqueVolumeName("fake/fake-device"), v1.UniqueVolumeName("fake/fake-device"),
stopCh, tCtx.Done(),
kubelet.volumeManager) kubelet.volumeManager)
assert.NoError(t, kubelet.volumeManager.WaitForAttachAndMount(context.Background(), pod)) assert.NoError(t, kubelet.volumeManager.WaitForAttachAndMount(context.Background(), pod))
@ -618,8 +626,9 @@ func TestVolumeUnmountAndDetachControllerEnabled(t *testing.T) {
}, },
}) })
stopCh := runVolumeManager(kubelet) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
go kubelet.volumeManager.Run(tCtx, kubelet.sourcesReady)
// Add pod // Add pod
kubelet.podManager.SetPods([]*v1.Pod{pod}) kubelet.podManager.SetPods([]*v1.Pod{pod})
@ -627,7 +636,7 @@ func TestVolumeUnmountAndDetachControllerEnabled(t *testing.T) {
// Fake node status update // Fake node status update
go simulateVolumeInUseUpdate( go simulateVolumeInUseUpdate(
v1.UniqueVolumeName("fake/fake-device"), v1.UniqueVolumeName("fake/fake-device"),
stopCh, tCtx.Done(),
kubelet.volumeManager) kubelet.volumeManager)
// Verify volumes attached // Verify volumes attached

View File

@ -50,7 +50,7 @@ import (
// if it has volumes. It also verifies that the pods in the desired state of the // if it has volumes. It also verifies that the pods in the desired state of the
// world cache still exist, if not, it removes them. // world cache still exist, if not, it removes them.
type DesiredStateOfWorldPopulator interface { type DesiredStateOfWorldPopulator interface {
Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) Run(ctx context.Context, sourcesReady config.SourcesReady)
// ReprocessPod sets value for the specified pod in processedPods // ReprocessPod sets value for the specified pod in processedPods
// to false, forcing it to be reprocessed. This is required to enable // to false, forcing it to be reprocessed. This is required to enable
@ -141,21 +141,22 @@ type processedPods struct {
sync.RWMutex sync.RWMutex
} }
func (dswp *desiredStateOfWorldPopulator) Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) { func (dswp *desiredStateOfWorldPopulator) Run(ctx context.Context, sourcesReady config.SourcesReady) {
// Wait for the completion of a loop that started after sources are all ready, then set hasAddedPods accordingly // Wait for the completion of a loop that started after sources are all ready, then set hasAddedPods accordingly
klog.InfoS("Desired state populator starts to run") logger := klog.FromContext(ctx)
wait.PollUntil(dswp.loopSleepDuration, func() (bool, error) { logger.Info("Desired state populator starts to run")
_ = wait.PollUntilContextCancel(ctx, dswp.loopSleepDuration, false, func(ctx context.Context) (bool, error) {
done := sourcesReady.AllReady() done := sourcesReady.AllReady()
dswp.populatorLoop() dswp.populatorLoop(ctx)
return done, nil return done, nil
}, stopCh) })
dswp.hasAddedPodsLock.Lock() dswp.hasAddedPodsLock.Lock()
if !dswp.hasAddedPods { if !dswp.hasAddedPods {
klog.InfoS("Finished populating initial desired state of world") logger.Info("Finished populating initial desired state of world")
dswp.hasAddedPods = true dswp.hasAddedPods = true
} }
dswp.hasAddedPodsLock.Unlock() dswp.hasAddedPodsLock.Unlock()
wait.Until(dswp.populatorLoop, dswp.loopSleepDuration, stopCh) wait.UntilWithContext(ctx, dswp.populatorLoop, dswp.loopSleepDuration)
} }
func (dswp *desiredStateOfWorldPopulator) ReprocessPod( func (dswp *desiredStateOfWorldPopulator) ReprocessPod(
@ -169,14 +170,14 @@ func (dswp *desiredStateOfWorldPopulator) HasAddedPods() bool {
return dswp.hasAddedPods return dswp.hasAddedPods
} }
func (dswp *desiredStateOfWorldPopulator) populatorLoop() { func (dswp *desiredStateOfWorldPopulator) populatorLoop(ctx context.Context) {
dswp.findAndAddNewPods() dswp.findAndAddNewPods(ctx)
dswp.findAndRemoveDeletedPods() dswp.findAndRemoveDeletedPods()
} }
// Iterate through all pods and add to desired state of world if they don't // Iterate through all pods and add to desired state of world if they don't
// exist but should // exist but should
func (dswp *desiredStateOfWorldPopulator) findAndAddNewPods() { func (dswp *desiredStateOfWorldPopulator) findAndAddNewPods(ctx context.Context) {
// Map unique pod name to outer volume name to MountedVolume. // Map unique pod name to outer volume name to MountedVolume.
mountedVolumesForPod := make(map[volumetypes.UniquePodName]map[string]cache.MountedVolume) mountedVolumesForPod := make(map[volumetypes.UniquePodName]map[string]cache.MountedVolume)
for _, mountedVolume := range dswp.actualStateOfWorld.GetMountedVolumes() { for _, mountedVolume := range dswp.actualStateOfWorld.GetMountedVolumes() {
@ -201,7 +202,7 @@ func (dswp *desiredStateOfWorldPopulator) findAndAddNewPods() {
continue continue
} }
dswp.processPodVolumes(pod, mountedVolumesForPod) dswp.processPodVolumes(ctx, pod, mountedVolumesForPod)
} }
} }
@ -284,12 +285,14 @@ func (dswp *desiredStateOfWorldPopulator) findAndRemoveDeletedPods() {
// processPodVolumes processes the volumes in the given pod and adds them to the // processPodVolumes processes the volumes in the given pod and adds them to the
// desired state of the world. // desired state of the world.
func (dswp *desiredStateOfWorldPopulator) processPodVolumes( func (dswp *desiredStateOfWorldPopulator) processPodVolumes(
ctx context.Context,
pod *v1.Pod, pod *v1.Pod,
mountedVolumesForPod map[volumetypes.UniquePodName]map[string]cache.MountedVolume) { mountedVolumesForPod map[volumetypes.UniquePodName]map[string]cache.MountedVolume) {
if pod == nil { if pod == nil {
return return
} }
logger := klog.FromContext(ctx)
uniquePodName := util.GetUniquePodName(pod) uniquePodName := util.GetUniquePodName(pod)
if dswp.podPreviouslyProcessed(uniquePodName) { if dswp.podPreviouslyProcessed(uniquePodName) {
return return
@ -302,14 +305,14 @@ func (dswp *desiredStateOfWorldPopulator) processPodVolumes(
for _, podVolume := range pod.Spec.Volumes { for _, podVolume := range pod.Spec.Volumes {
if !mounts.Has(podVolume.Name) && !devices.Has(podVolume.Name) { if !mounts.Has(podVolume.Name) && !devices.Has(podVolume.Name) {
// Volume is not used in the pod, ignore it. // Volume is not used in the pod, ignore it.
klog.V(4).InfoS("Skipping unused volume", "pod", klog.KObj(pod), "volumeName", podVolume.Name) logger.V(4).Info("Skipping unused volume", "pod", klog.KObj(pod), "volumeName", podVolume.Name)
continue continue
} }
pvc, volumeSpec, volumeGidValue, err := pvc, volumeSpec, volumeGidValue, err :=
dswp.createVolumeSpec(podVolume, pod, mounts, devices) dswp.createVolumeSpec(logger, podVolume, pod, mounts, devices)
if err != nil { if err != nil {
klog.ErrorS(err, "Error processing volume", "pod", klog.KObj(pod), "volumeName", podVolume.Name) logger.Error(err, "Error processing volume", "pod", klog.KObj(pod), "volumeName", podVolume.Name)
dswp.desiredStateOfWorld.AddErrorToPod(uniquePodName, err.Error()) dswp.desiredStateOfWorld.AddErrorToPod(uniquePodName, err.Error())
allVolumesAdded = false allVolumesAdded = false
continue continue
@ -319,11 +322,11 @@ func (dswp *desiredStateOfWorldPopulator) processPodVolumes(
_, err = dswp.desiredStateOfWorld.AddPodToVolume( _, err = dswp.desiredStateOfWorld.AddPodToVolume(
uniquePodName, pod, volumeSpec, podVolume.Name, volumeGidValue, seLinuxContainerContexts[podVolume.Name]) uniquePodName, pod, volumeSpec, podVolume.Name, volumeGidValue, seLinuxContainerContexts[podVolume.Name])
if err != nil { if err != nil {
klog.ErrorS(err, "Failed to add volume to desiredStateOfWorld", "pod", klog.KObj(pod), "volumeName", podVolume.Name, "volumeSpecName", volumeSpec.Name()) logger.Error(err, "Failed to add volume to desiredStateOfWorld", "pod", klog.KObj(pod), "volumeName", podVolume.Name, "volumeSpecName", volumeSpec.Name())
dswp.desiredStateOfWorld.AddErrorToPod(uniquePodName, err.Error()) dswp.desiredStateOfWorld.AddErrorToPod(uniquePodName, err.Error())
allVolumesAdded = false allVolumesAdded = false
} else { } else {
klog.V(4).InfoS("Added volume to desired state", "pod", klog.KObj(pod), "volumeName", podVolume.Name, "volumeSpecName", volumeSpec.Name()) logger.V(4).Info("Added volume to desired state", "pod", klog.KObj(pod), "volumeName", podVolume.Name, "volumeSpecName", volumeSpec.Name())
} }
dswp.checkVolumeFSResize(pod, podVolume, pvc, volumeSpec, uniquePodName, mountedVolumesForPod) dswp.checkVolumeFSResize(pod, podVolume, pvc, volumeSpec, uniquePodName, mountedVolumesForPod)
@ -455,7 +458,7 @@ func (dswp *desiredStateOfWorldPopulator) deleteProcessedPod(
// specified volume. It dereference any PVC to get PV objects, if needed. // specified volume. It dereference any PVC to get PV objects, if needed.
// Returns an error if unable to obtain the volume at this time. // Returns an error if unable to obtain the volume at this time.
func (dswp *desiredStateOfWorldPopulator) createVolumeSpec( func (dswp *desiredStateOfWorldPopulator) createVolumeSpec(
podVolume v1.Volume, pod *v1.Pod, mounts, devices sets.Set[string]) (*v1.PersistentVolumeClaim, *volume.Spec, string, error) { logger klog.Logger, podVolume v1.Volume, pod *v1.Pod, mounts, devices sets.Set[string]) (*v1.PersistentVolumeClaim, *volume.Spec, string, error) {
pvcSource := podVolume.VolumeSource.PersistentVolumeClaim pvcSource := podVolume.VolumeSource.PersistentVolumeClaim
isEphemeral := pvcSource == nil && podVolume.VolumeSource.Ephemeral != nil isEphemeral := pvcSource == nil && podVolume.VolumeSource.Ephemeral != nil
if isEphemeral { if isEphemeral {
@ -468,7 +471,7 @@ func (dswp *desiredStateOfWorldPopulator) createVolumeSpec(
} }
} }
if pvcSource != nil { if pvcSource != nil {
klog.V(5).InfoS("Found PVC", "PVC", klog.KRef(pod.Namespace, pvcSource.ClaimName)) logger.V(5).Info("Found PVC", "PVC", klog.KRef(pod.Namespace, pvcSource.ClaimName))
// If podVolume is a PVC, fetch the real PV behind the claim // If podVolume is a PVC, fetch the real PV behind the claim
pvc, err := dswp.getPVCExtractPV( pvc, err := dswp.getPVCExtractPV(
pod.Namespace, pvcSource.ClaimName) pod.Namespace, pvcSource.ClaimName)
@ -485,7 +488,7 @@ func (dswp *desiredStateOfWorldPopulator) createVolumeSpec(
} }
} }
pvName, pvcUID := pvc.Spec.VolumeName, pvc.UID pvName, pvcUID := pvc.Spec.VolumeName, pvc.UID
klog.V(5).InfoS("Found bound PV for PVC", "PVC", klog.KRef(pod.Namespace, pvcSource.ClaimName), "PVCUID", pvcUID, "PVName", pvName) logger.V(5).Info("Found bound PV for PVC", "PVC", klog.KRef(pod.Namespace, pvcSource.ClaimName), "PVCUID", pvcUID, "PVName", pvName)
// Fetch actual PV object // Fetch actual PV object
volumeSpec, volumeGidValue, err := volumeSpec, volumeGidValue, err :=
dswp.getPVSpec(pvName, pvcSource.ReadOnly, pvcUID) dswp.getPVSpec(pvName, pvcSource.ReadOnly, pvcUID)
@ -496,13 +499,13 @@ func (dswp *desiredStateOfWorldPopulator) createVolumeSpec(
pvcSource.ClaimName, pvcSource.ClaimName,
err) err)
} }
klog.V(5).InfoS("Extracted volumeSpec from bound PV and PVC", "PVC", klog.KRef(pod.Namespace, pvcSource.ClaimName), "PVCUID", pvcUID, "PVName", pvName, "volumeSpecName", volumeSpec.Name()) logger.V(5).Info("Extracted volumeSpec from bound PV and PVC", "PVC", klog.KRef(pod.Namespace, pvcSource.ClaimName), "PVCUID", pvcUID, "PVName", pvName, "volumeSpecName", volumeSpec.Name())
migratable, err := dswp.csiMigratedPluginManager.IsMigratable(volumeSpec) migratable, err := dswp.csiMigratedPluginManager.IsMigratable(volumeSpec)
if err != nil { if err != nil {
return nil, nil, "", err return nil, nil, "", err
} }
if migratable { if migratable {
volumeSpec, err = csimigration.TranslateInTreeSpecToCSI(volumeSpec, pod.Namespace, dswp.intreeToCSITranslator) volumeSpec, err = csimigration.TranslateInTreeSpecToCSI(logger, volumeSpec, pod.Namespace, dswp.intreeToCSITranslator)
if err != nil { if err != nil {
return nil, nil, "", err return nil, nil, "", err
} }
@ -538,7 +541,7 @@ func (dswp *desiredStateOfWorldPopulator) createVolumeSpec(
return nil, nil, "", err return nil, nil, "", err
} }
if migratable { if migratable {
spec, err = csimigration.TranslateInTreeSpecToCSI(spec, pod.Namespace, dswp.intreeToCSITranslator) spec, err = csimigration.TranslateInTreeSpecToCSI(logger, spec, pod.Namespace, dswp.intreeToCSITranslator)
if err != nil { if err != nil {
return nil, nil, "", err return nil, nil, "", err
} }

View File

@ -17,14 +17,11 @@ limitations under the License.
package populator package populator
import ( import (
"context"
"fmt"
"testing" "testing"
"time" "time"
"k8s.io/klog/v2/ktesting"
"k8s.io/utils/ptr"
"fmt"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
@ -46,6 +43,8 @@ import (
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/operationexecutor" "k8s.io/kubernetes/pkg/volume/util/operationexecutor"
"k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/test/utils/ktesting"
"k8s.io/utils/ptr"
) )
const ( const (
@ -165,7 +164,8 @@ func TestFindAndAddNewPods_WithDifferentConditions(t *testing.T) {
dswp.hasAddedPods = tc.hasAddedPods dswp.hasAddedPods = tc.hasAddedPods
// Action // Action
dswp.findAndAddNewPods() tCtx := ktesting.Init(t)
dswp.findAndAddNewPods(tCtx)
// Verify // Verify
podsInDSW := dswp.desiredStateOfWorld.GetPods() podsInDSW := dswp.desiredStateOfWorld.GetPods()
@ -204,7 +204,8 @@ func TestFindAndAddNewPods_WithReprocessPodAndVolumeRetrievalError(t *testing.T)
podName := util.GetUniquePodName(pod) podName := util.GetUniquePodName(pod)
dswp.findAndAddNewPods() tCtx := ktesting.Init(t)
dswp.findAndAddNewPods(tCtx)
if !dswp.podPreviouslyProcessed(podName) { if !dswp.podPreviouslyProcessed(podName) {
t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName) t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName)
@ -212,7 +213,7 @@ func TestFindAndAddNewPods_WithReprocessPodAndVolumeRetrievalError(t *testing.T)
pluginPVOmittingClient(dswp) pluginPVOmittingClient(dswp)
dswp.ReprocessPod(podName) dswp.ReprocessPod(podName)
dswp.findAndAddNewPods() dswp.findAndAddNewPods(tCtx)
if !dswp.podPreviouslyProcessed(podName) { if !dswp.podPreviouslyProcessed(podName) {
t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName) t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName)
@ -243,7 +244,8 @@ func TestFindAndAddNewPods_WithVolumeRetrievalError(t *testing.T) {
podName := util.GetUniquePodName(pod) podName := util.GetUniquePodName(pod)
dswp.findAndAddNewPods() tCtx := ktesting.Init(t)
dswp.findAndAddNewPods(tCtx)
if dswp.podPreviouslyProcessed(podName) { if dswp.podPreviouslyProcessed(podName) {
t.Fatalf("The volumes for the specified pod: %s should not have been processed by the populator", podName) t.Fatalf("The volumes for the specified pod: %s should not have been processed by the populator", podName)
@ -485,7 +487,8 @@ func prepareDSWPWithPodPV(t *testing.T) (*desiredStateOfWorldPopulator, *fakePod
generatedVolumeName := "fake-plugin/" + pod.Spec.Volumes[0].Name generatedVolumeName := "fake-plugin/" + pod.Spec.Volumes[0].Name
dswp.findAndAddNewPods() tCtx := ktesting.Init(t)
dswp.findAndAddNewPods(tCtx)
if !dswp.pods.processedPods[podName] { if !dswp.pods.processedPods[podName] {
t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName) t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName)
@ -535,7 +538,7 @@ func TestFindAndRemoveNonattachableVolumes(t *testing.T) {
} }
fakeVolumePluginMgr, fakeVolumePlugin := volumetesting.GetTestKubeletVolumePluginMgr(t) fakeVolumePluginMgr, fakeVolumePlugin := volumetesting.GetTestKubeletVolumePluginMgr(t)
dswp, fakePodManager, fakesDSW, _, _ := createDswpWithVolumeWithCustomPluginMgr(t, pv, pvc, fakeVolumePluginMgr) dswp, fakePodManager, fakesDSW, _, _ := createDswpWithVolumeWithCustomPluginMgr(pv, pvc, fakeVolumePluginMgr)
// create pod // create pod
containers := []v1.Container{ containers := []v1.Container{
@ -556,7 +559,8 @@ func TestFindAndRemoveNonattachableVolumes(t *testing.T) {
generatedVolumeName := "fake-plugin/" + pod.Spec.Volumes[0].Name generatedVolumeName := "fake-plugin/" + pod.Spec.Volumes[0].Name
dswp.findAndAddNewPods() tCtx := ktesting.Init(t)
dswp.findAndAddNewPods(tCtx)
if !dswp.pods.processedPods[podName] { if !dswp.pods.processedPods[podName] {
t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName) t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName)
@ -602,7 +606,8 @@ func TestEphemeralVolumeOwnerCheck(t *testing.T) {
podName := util.GetUniquePodName(pod) podName := util.GetUniquePodName(pod)
dswp.findAndAddNewPods() tCtx := ktesting.Init(t)
dswp.findAndAddNewPods(tCtx)
if dswp.pods.processedPods[podName] { if dswp.pods.processedPods[podName] {
t.Fatalf("%s should not have been processed by the populator", podName) t.Fatalf("%s should not have been processed by the populator", podName)
} }
@ -656,7 +661,8 @@ func TestFindAndAddNewPods_FindAndRemoveDeletedPods_Valid_Block_VolumeDevices(t
generatedVolumeName := "fake-plugin/" + pod.Spec.Volumes[0].Name generatedVolumeName := "fake-plugin/" + pod.Spec.Volumes[0].Name
dswp.findAndAddNewPods() tCtx := ktesting.Init(t)
dswp.findAndAddNewPods(tCtx)
if !dswp.pods.processedPods[podName] { if !dswp.pods.processedPods[podName] {
t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName) t.Fatalf("Failed to record that the volumes for the specified pod: %s have been processed by the populator", podName)
@ -758,10 +764,11 @@ func TestCreateVolumeSpec_Valid_File_VolumeMounts(t *testing.T) {
} }
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers) pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers)
logger, _ := ktesting.NewTestContext(t)
fakePodManager.AddPod(pod) fakePodManager.AddPod(pod)
mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod)
_, volumeSpec, _, err := _, volumeSpec, _, err :=
dswp.createVolumeSpec(pod.Spec.Volumes[0], pod, mountsMap, devicesMap) dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap)
// Assert // Assert
if volumeSpec == nil || err != nil { if volumeSpec == nil || err != nil {
@ -804,10 +811,11 @@ func TestCreateVolumeSpec_Valid_Nil_VolumeMounts(t *testing.T) {
} }
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers) pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers)
logger, _ := ktesting.NewTestContext(t)
fakePodManager.AddPod(pod) fakePodManager.AddPod(pod)
mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod)
_, volumeSpec, _, err := _, volumeSpec, _, err :=
dswp.createVolumeSpec(pod.Spec.Volumes[0], pod, mountsMap, devicesMap) dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap)
// Assert // Assert
if volumeSpec == nil || err != nil { if volumeSpec == nil || err != nil {
@ -850,10 +858,11 @@ func TestCreateVolumeSpec_Valid_Block_VolumeDevices(t *testing.T) {
} }
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "block-bound", containers) pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "block-bound", containers)
logger, _ := ktesting.NewTestContext(t)
fakePodManager.AddPod(pod) fakePodManager.AddPod(pod)
mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod)
_, volumeSpec, _, err := _, volumeSpec, _, err :=
dswp.createVolumeSpec(pod.Spec.Volumes[0], pod, mountsMap, devicesMap) dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap)
// Assert // Assert
if volumeSpec == nil || err != nil { if volumeSpec == nil || err != nil {
@ -896,10 +905,11 @@ func TestCreateVolumeSpec_Invalid_File_VolumeDevices(t *testing.T) {
} }
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers) pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "file-bound", containers)
logger, _ := ktesting.NewTestContext(t)
fakePodManager.AddPod(pod) fakePodManager.AddPod(pod)
mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod)
_, volumeSpec, _, err := _, volumeSpec, _, err :=
dswp.createVolumeSpec(pod.Spec.Volumes[0], pod, mountsMap, devicesMap) dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap)
// Assert // Assert
if volumeSpec != nil || err == nil { if volumeSpec != nil || err == nil {
@ -942,10 +952,11 @@ func TestCreateVolumeSpec_Invalid_Block_VolumeMounts(t *testing.T) {
} }
pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "block-bound", containers) pod := createPodWithVolume("dswp-test-pod", "dswp-test-volume-name", "block-bound", containers)
logger, _ := ktesting.NewTestContext(t)
fakePodManager.AddPod(pod) fakePodManager.AddPod(pod)
mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod) mountsMap, devicesMap, _ := util.GetPodVolumeNames(pod)
_, volumeSpec, _, err := _, volumeSpec, _, err :=
dswp.createVolumeSpec(pod.Spec.Volumes[0], pod, mountsMap, devicesMap) dswp.createVolumeSpec(logger, pod.Spec.Volumes[0], pod, mountsMap, devicesMap)
// Assert // Assert
if volumeSpec != nil || err == nil { if volumeSpec != nil || err == nil {
@ -1104,13 +1115,14 @@ func TestCheckVolumeFSResize(t *testing.T) {
fakePodManager.AddPod(pod) fakePodManager.AddPod(pod)
// Fill the dsw to contains volumes and pods. // Fill the dsw to contains volumes and pods.
dswp.findAndAddNewPods() tCtx := ktesting.Init(t)
dswp.findAndAddNewPods(tCtx)
reconcileASW(fakeASW, fakeDSW, t) reconcileASW(fakeASW, fakeDSW, t)
func() { func() {
tc.resize(t, pv, pvc, dswp) tc.resize(t, pv, pvc, dswp)
resizeRequiredVolumes := reprocess(dswp, uniquePodName, fakeDSW, fakeASW, *pv.Spec.Capacity.Storage()) resizeRequiredVolumes := reprocess(tCtx, dswp, uniquePodName, fakeDSW, fakeASW, *pv.Spec.Capacity.Storage())
tc.verify(t, resizeRequiredVolumes, uniqueVolumeName) tc.verify(t, resizeRequiredVolumes, uniqueVolumeName)
}() }()
@ -1279,8 +1291,9 @@ func TestCheckVolumeSELinux(t *testing.T) {
fakeVolumePluginMgr, plugin := volumetesting.GetTestKubeletVolumePluginMgr(t) fakeVolumePluginMgr, plugin := volumetesting.GetTestKubeletVolumePluginMgr(t)
plugin.SupportsSELinux = tc.pluginSupportsSELinux plugin.SupportsSELinux = tc.pluginSupportsSELinux
dswp, fakePodManager, fakeDSW, _, _ := createDswpWithVolumeWithCustomPluginMgr(t, pv, pvc, fakeVolumePluginMgr) dswp, fakePodManager, fakeDSW, _, _ := createDswpWithVolumeWithCustomPluginMgr(pv, pvc, fakeVolumePluginMgr)
tCtx := ktesting.Init(t)
var existingPod *v1.Pod var existingPod *v1.Pod
if tc.existingContainerSELinuxOpts != nil { if tc.existingContainerSELinuxOpts != nil {
// Add existing pod + volume // Add existing pod + volume
@ -1288,7 +1301,7 @@ func TestCheckVolumeSELinux(t *testing.T) {
existingContainer.SecurityContext.SELinuxOptions = tc.existingContainerSELinuxOpts existingContainer.SecurityContext.SELinuxOptions = tc.existingContainerSELinuxOpts
existingPod = createPodWithVolume("dswp-old-pod", "dswp-test-volume-name", "file-bound", []v1.Container{existingContainer}) existingPod = createPodWithVolume("dswp-old-pod", "dswp-test-volume-name", "file-bound", []v1.Container{existingContainer})
fakePodManager.AddPod(existingPod) fakePodManager.AddPod(existingPod)
dswp.findAndAddNewPods() dswp.findAndAddNewPods(tCtx)
} }
newContainer := container newContainer := container
@ -1297,7 +1310,7 @@ func TestCheckVolumeSELinux(t *testing.T) {
// Act - add the new Pod // Act - add the new Pod
fakePodManager.AddPod(newPod) fakePodManager.AddPod(newPod)
dswp.findAndAddNewPods() dswp.findAndAddNewPods(tCtx)
// Assert // Assert
@ -1402,10 +1415,10 @@ func clearASW(asw cache.ActualStateOfWorld, dsw cache.DesiredStateOfWorld, t *te
} }
} }
func reprocess(dswp *desiredStateOfWorldPopulator, uniquePodName types.UniquePodName, func reprocess(ctx context.Context, dswp *desiredStateOfWorldPopulator, uniquePodName types.UniquePodName,
dsw cache.DesiredStateOfWorld, asw cache.ActualStateOfWorld, newSize resource.Quantity) []v1.UniqueVolumeName { dsw cache.DesiredStateOfWorld, asw cache.ActualStateOfWorld, newSize resource.Quantity) []v1.UniqueVolumeName {
dswp.ReprocessPod(uniquePodName) dswp.ReprocessPod(uniquePodName)
dswp.findAndAddNewPods() dswp.findAndAddNewPods(ctx)
return getResizeRequiredVolumes(dsw, asw, newSize) return getResizeRequiredVolumes(dsw, asw, newSize)
} }
@ -1544,7 +1557,7 @@ func createEphemeralVolumeObjects(podName, volumeName string, owned bool, volume
func createDswpWithVolume(t *testing.T, pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim) (*desiredStateOfWorldPopulator, kubepod.Manager, cache.DesiredStateOfWorld, *containertest.FakeRuntime, *fakePodStateProvider) { func createDswpWithVolume(t *testing.T, pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim) (*desiredStateOfWorldPopulator, kubepod.Manager, cache.DesiredStateOfWorld, *containertest.FakeRuntime, *fakePodStateProvider) {
fakeVolumePluginMgr, _ := volumetesting.GetTestKubeletVolumePluginMgr(t) fakeVolumePluginMgr, _ := volumetesting.GetTestKubeletVolumePluginMgr(t)
dswp, fakePodManager, fakesDSW, fakeRuntime, fakeStateProvider := createDswpWithVolumeWithCustomPluginMgr(t, pv, pvc, fakeVolumePluginMgr) dswp, fakePodManager, fakesDSW, fakeRuntime, fakeStateProvider := createDswpWithVolumeWithCustomPluginMgr(pv, pvc, fakeVolumePluginMgr)
return dswp, fakePodManager, fakesDSW, fakeRuntime, fakeStateProvider return dswp, fakePodManager, fakesDSW, fakeRuntime, fakeStateProvider
} }
@ -1567,7 +1580,7 @@ func (p *fakePodStateProvider) ShouldPodRuntimeBeRemoved(uid kubetypes.UID) bool
return ok return ok
} }
func createDswpWithVolumeWithCustomPluginMgr(t *testing.T, pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim, func createDswpWithVolumeWithCustomPluginMgr(pv *v1.PersistentVolume, pvc *v1.PersistentVolumeClaim,
fakeVolumePluginMgr *volume.VolumePluginMgr) (*desiredStateOfWorldPopulator, kubepod.Manager, cache.DesiredStateOfWorld, *containertest.FakeRuntime, *fakePodStateProvider) { fakeVolumePluginMgr *volume.VolumePluginMgr) (*desiredStateOfWorldPopulator, kubepod.Manager, cache.DesiredStateOfWorld, *containertest.FakeRuntime, *fakePodStateProvider) {
fakeClient := &fake.Clientset{} fakeClient := &fake.Clientset{}
fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) { fakeClient.AddReactor("get", "persistentvolumeclaims", func(action core.Action) (bool, runtime.Object, error) {

View File

@ -39,6 +39,8 @@ import (
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/klog/v2/ktesting"
_ "k8s.io/klog/v2/ktesting/init"
"k8s.io/kubernetes/pkg/kubelet/volumemanager/cache" "k8s.io/kubernetes/pkg/kubelet/volumemanager/cache"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumetesting "k8s.io/kubernetes/pkg/volume/testing" volumetesting "k8s.io/kubernetes/pkg/volume/testing"
@ -188,6 +190,7 @@ func Test_Run_Positive_VolumeAttachAndMount(t *testing.T) {
// Verifies there is are attach/mount/etc calls and no detach/unmount calls. // Verifies there is are attach/mount/etc calls and no detach/unmount calls.
func Test_Run_Positive_VolumeAttachAndMountMigrationEnabled(t *testing.T) { func Test_Run_Positive_VolumeAttachAndMountMigrationEnabled(t *testing.T) {
// Arrange // Arrange
logger, _ := ktesting.NewTestContext(t)
intreeToCSITranslator := csitrans.New() intreeToCSITranslator := csitrans.New()
node := &v1.Node{ node := &v1.Node{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -254,7 +257,7 @@ func Test_Run_Positive_VolumeAttachAndMountMigrationEnabled(t *testing.T) {
} }
volumeSpec := &volume.Spec{Volume: &pod.Spec.Volumes[0]} volumeSpec := &volume.Spec{Volume: &pod.Spec.Volumes[0]}
migratedSpec, err := csimigration.TranslateInTreeSpecToCSI(volumeSpec, pod.Namespace, intreeToCSITranslator) migratedSpec, err := csimigration.TranslateInTreeSpecToCSI(logger, volumeSpec, pod.Namespace, intreeToCSITranslator)
if err != nil { if err != nil {
t.Fatalf("unexpected error while translating spec %v: %v", volumeSpec, err) t.Fatalf("unexpected error while translating spec %v: %v", volumeSpec, err)
} }

View File

@ -90,7 +90,7 @@ const (
// this node and makes it so. // this node and makes it so.
type VolumeManager interface { type VolumeManager interface {
// Starts the volume manager and all the asynchronous loops that it controls // Starts the volume manager and all the asynchronous loops that it controls
Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) Run(ctx context.Context, sourcesReady config.SourcesReady)
// WaitForAttachAndMount processes the volumes referenced in the specified // WaitForAttachAndMount processes the volumes referenced in the specified
// pod and blocks until they are all attached and mounted (reflected in // pod and blocks until they are all attached and mounted (reflected in
@ -275,23 +275,23 @@ type volumeManager struct {
intreeToCSITranslator csimigration.InTreeToCSITranslator intreeToCSITranslator csimigration.InTreeToCSITranslator
} }
func (vm *volumeManager) Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) { func (vm *volumeManager) Run(ctx context.Context, sourcesReady config.SourcesReady) {
defer runtime.HandleCrash() defer runtime.HandleCrash()
if vm.kubeClient != nil { if vm.kubeClient != nil {
// start informer for CSIDriver // start informer for CSIDriver
go vm.volumePluginMgr.Run(stopCh) go vm.volumePluginMgr.Run(ctx.Done())
} }
go vm.desiredStateOfWorldPopulator.Run(sourcesReady, stopCh) go vm.desiredStateOfWorldPopulator.Run(ctx, sourcesReady)
klog.V(2).InfoS("The desired_state_of_world populator starts") klog.V(2).InfoS("The desired_state_of_world populator starts")
klog.InfoS("Starting Kubelet Volume Manager") klog.InfoS("Starting Kubelet Volume Manager")
go vm.reconciler.Run(stopCh) go vm.reconciler.Run(ctx.Done())
metrics.Register(vm.actualStateOfWorld, vm.desiredStateOfWorld, vm.volumePluginMgr) metrics.Register(vm.actualStateOfWorld, vm.desiredStateOfWorld, vm.volumePluginMgr)
<-stopCh <-ctx.Done()
klog.InfoS("Shutting down Kubelet Volume Manager") klog.InfoS("Shutting down Kubelet Volume Manager")
} }

View File

@ -44,7 +44,7 @@ func NewFakeVolumeManager(initialVolumes []v1.UniqueVolumeName) *FakeVolumeManag
} }
// Run is not implemented // Run is not implemented
func (f *FakeVolumeManager) Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) { func (f *FakeVolumeManager) Run(ctx context.Context, sourcesReady config.SourcesReady) {
} }
// WaitForAttachAndMount is not implemented // WaitForAttachAndMount is not implemented

View File

@ -25,8 +25,6 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/mount-utils"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubetypes "k8s.io/apimachinery/pkg/types" kubetypes "k8s.io/apimachinery/pkg/types"
@ -44,6 +42,8 @@ import (
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/hostutil" "k8s.io/kubernetes/pkg/volume/util/hostutil"
"k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/kubernetes/test/utils/ktesting"
"k8s.io/mount-utils"
) )
const ( const (
@ -94,15 +94,17 @@ func TestGetMountedVolumesForPodAndGetVolumesInUse(t *testing.T) {
manager := newTestVolumeManager(t, tmpDir, podManager, kubeClient, node) manager := newTestVolumeManager(t, tmpDir, podManager, kubeClient, node)
stopCh := runVolumeManager(manager) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
sourcesReady := config.NewSourcesReady(func(_ sets.Set[string]) bool { return true })
go manager.Run(tCtx, sourcesReady)
podManager.SetPods([]*v1.Pod{pod}) podManager.SetPods([]*v1.Pod{pod})
// Fake node status update // Fake node status update
go simulateVolumeInUseUpdate( go simulateVolumeInUseUpdate(
v1.UniqueVolumeName(node.Status.VolumesAttached[0].Name), v1.UniqueVolumeName(node.Status.VolumesAttached[0].Name),
stopCh, tCtx.Done(),
manager) manager)
err = manager.WaitForAttachAndMount(context.Background(), pod) err = manager.WaitForAttachAndMount(context.Background(), pod)
@ -218,8 +220,10 @@ func TestWaitForAttachAndMountError(t *testing.T) {
manager := newTestVolumeManager(t, tmpDir, podManager, kubeClient, nil) manager := newTestVolumeManager(t, tmpDir, podManager, kubeClient, nil)
stopCh := runVolumeManager(manager) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
sourcesReady := config.NewSourcesReady(func(_ sets.Set[string]) bool { return true })
go manager.Run(tCtx, sourcesReady)
podManager.SetPods([]*v1.Pod{pod}) podManager.SetPods([]*v1.Pod{pod})
@ -250,15 +254,17 @@ func TestInitialPendingVolumesForPodAndGetVolumesInUse(t *testing.T) {
manager := newTestVolumeManager(t, tmpDir, podManager, kubeClient, node) manager := newTestVolumeManager(t, tmpDir, podManager, kubeClient, node)
stopCh := runVolumeManager(manager) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
sourcesReady := config.NewSourcesReady(func(_ sets.Set[string]) bool { return true })
go manager.Run(tCtx, sourcesReady)
podManager.SetPods([]*v1.Pod{pod}) podManager.SetPods([]*v1.Pod{pod})
// Fake node status update // Fake node status update
go simulateVolumeInUseUpdate( go simulateVolumeInUseUpdate(
v1.UniqueVolumeName(node.Status.VolumesAttached[0].Name), v1.UniqueVolumeName(node.Status.VolumesAttached[0].Name),
stopCh, tCtx.Done(),
manager) manager)
// delayed claim binding // delayed claim binding
@ -338,15 +344,17 @@ func TestGetExtraSupplementalGroupsForPod(t *testing.T) {
manager := newTestVolumeManager(t, tmpDir, podManager, kubeClient, node) manager := newTestVolumeManager(t, tmpDir, podManager, kubeClient, node)
stopCh := runVolumeManager(manager) tCtx := ktesting.Init(t)
defer close(stopCh) defer tCtx.Cancel("test has completed")
sourcesReady := config.NewSourcesReady(func(_ sets.Set[string]) bool { return true })
go manager.Run(tCtx, sourcesReady)
podManager.SetPods([]*v1.Pod{pod}) podManager.SetPods([]*v1.Pod{pod})
// Fake node status update // Fake node status update
go simulateVolumeInUseUpdate( go simulateVolumeInUseUpdate(
v1.UniqueVolumeName(node.Status.VolumesAttached[0].Name), v1.UniqueVolumeName(node.Status.VolumesAttached[0].Name),
stopCh, tCtx.Done(),
manager) manager)
err = manager.WaitForAttachAndMount(context.Background(), pod) err = manager.WaitForAttachAndMount(context.Background(), pod)
@ -537,12 +545,3 @@ func delayClaimBecomesBound(
} }
kubeClient.CoreV1().PersistentVolumeClaims(namespace).Update(context.TODO(), volumeClaim, metav1.UpdateOptions{}) kubeClient.CoreV1().PersistentVolumeClaims(namespace).Update(context.TODO(), volumeClaim, metav1.UpdateOptions{})
} }
func runVolumeManager(manager VolumeManager) chan struct{} {
stopCh := make(chan struct{})
//readyCh := make(chan bool, 1)
//readyCh <- true
sourcesReady := config.NewSourcesReady(func(_ sets.Set[string]) bool { return true })
go manager.Run(sourcesReady, stopCh)
return stopCh
}

View File

@ -46,8 +46,8 @@ type InTreeToCSITranslator interface {
IsMigratableIntreePluginByName(inTreePluginName string) bool IsMigratableIntreePluginByName(inTreePluginName string) bool
GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error) GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error)
GetCSINameFromInTreeName(pluginName string) (string, error) GetCSINameFromInTreeName(pluginName string) (string, error)
TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error)
TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error)
} }
// CSILimits is a plugin that checks node volume limits. // CSILimits is a plugin that checks node volume limits.
@ -293,7 +293,7 @@ func (pl *CSILimits) checkAttachableInlineVolume(logger klog.Logger, vol *v1.Vol
return nil return nil
} }
// Do translation for the in-tree volume. // Do translation for the in-tree volume.
translatedPV, err := pl.translator.TranslateInTreeInlineVolumeToCSI(vol, pod.Namespace) translatedPV, err := pl.translator.TranslateInTreeInlineVolumeToCSI(logger, vol, pod.Namespace)
if err != nil || translatedPV == nil { if err != nil || translatedPV == nil {
return fmt.Errorf("converting volume(%s) from inline to csi: %w", vol.Name, err) return fmt.Errorf("converting volume(%s) from inline to csi: %w", vol.Name, err)
} }
@ -350,7 +350,7 @@ func (pl *CSILimits) getCSIDriverInfo(logger klog.Logger, csiNode *storagev1.CSI
return "", "" return "", ""
} }
csiPV, err := pl.translator.TranslateInTreePVToCSI(pv) csiPV, err := pl.translator.TranslateInTreePVToCSI(logger, pv)
if err != nil { if err != nil {
logger.V(5).Info("Unable to translate in-tree volume to CSI", "err", err) logger.V(5).Info("Unable to translate in-tree volume to CSI", "err", err)
return "", "" return "", ""

View File

@ -117,7 +117,7 @@ type PodVolumes struct {
type InTreeToCSITranslator interface { type InTreeToCSITranslator interface {
IsPVMigratable(pv *v1.PersistentVolume) bool IsPVMigratable(pv *v1.PersistentVolume) bool
GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error) GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error)
TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error)
} }
// SchedulerVolumeBinder is used by the scheduler VolumeBinding plugin to // SchedulerVolumeBinder is used by the scheduler VolumeBinding plugin to
@ -673,7 +673,7 @@ func (b *volumeBinder) checkBindings(logger klog.Logger, pod *v1.Pod, bindings [
return false, nil return false, nil
} }
pv, err = b.tryTranslatePVToCSI(pv, csiNode) pv, err = b.tryTranslatePVToCSI(logger, pv, csiNode)
if err != nil { if err != nil {
return false, fmt.Errorf("failed to translate pv to csi: %w", err) return false, fmt.Errorf("failed to translate pv to csi: %w", err)
} }
@ -732,7 +732,7 @@ func (b *volumeBinder) checkBindings(logger klog.Logger, pod *v1.Pod, bindings [
return false, fmt.Errorf("failed to get pv %q from cache: %w", pvc.Spec.VolumeName, err) return false, fmt.Errorf("failed to get pv %q from cache: %w", pvc.Spec.VolumeName, err)
} }
pv, err = b.tryTranslatePVToCSI(pv, csiNode) pv, err = b.tryTranslatePVToCSI(logger, pv, csiNode)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -881,7 +881,7 @@ func (b *volumeBinder) checkBoundClaims(logger klog.Logger, claims []*v1.Persist
return true, false, err return true, false, err
} }
pv, err = b.tryTranslatePVToCSI(pv, csiNode) pv, err = b.tryTranslatePVToCSI(logger, pv, csiNode)
if err != nil { if err != nil {
return false, true, err return false, true, err
} }
@ -1128,7 +1128,7 @@ func isPluginMigratedToCSIOnNode(pluginName string, csiNode *storagev1.CSINode)
} }
// tryTranslatePVToCSI will translate the in-tree PV to CSI if it meets the criteria. If not, it returns the unmodified in-tree PV. // tryTranslatePVToCSI will translate the in-tree PV to CSI if it meets the criteria. If not, it returns the unmodified in-tree PV.
func (b *volumeBinder) tryTranslatePVToCSI(pv *v1.PersistentVolume, csiNode *storagev1.CSINode) (*v1.PersistentVolume, error) { func (b *volumeBinder) tryTranslatePVToCSI(logger klog.Logger, pv *v1.PersistentVolume, csiNode *storagev1.CSINode) (*v1.PersistentVolume, error) {
if !b.translator.IsPVMigratable(pv) { if !b.translator.IsPVMigratable(pv) {
return pv, nil return pv, nil
} }
@ -1146,7 +1146,7 @@ func (b *volumeBinder) tryTranslatePVToCSI(pv *v1.PersistentVolume, csiNode *sto
return pv, nil return pv, nil
} }
transPV, err := b.translator.TranslateInTreePVToCSI(pv) transPV, err := b.translator.TranslateInTreePVToCSI(logger, pv)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not translate pv: %v", err) return nil, fmt.Errorf("could not translate pv: %v", err)
} }

View File

@ -23,6 +23,7 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/component-base/featuregate" "k8s.io/component-base/featuregate"
csilibplugins "k8s.io/csi-translation-lib/plugins" csilibplugins "k8s.io/csi-translation-lib/plugins"
"k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
) )
@ -123,20 +124,20 @@ func (pm PluginManager) IsMigratable(spec *volume.Spec) (bool, error) {
// InTreeToCSITranslator performs translation of Volume sources for PV and Volume objects // InTreeToCSITranslator performs translation of Volume sources for PV and Volume objects
// from references to in-tree plugins to migrated CSI plugins // from references to in-tree plugins to migrated CSI plugins
type InTreeToCSITranslator interface { type InTreeToCSITranslator interface {
TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error)
TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error)
} }
// TranslateInTreeSpecToCSI translates a volume spec (either PV or inline volume) // TranslateInTreeSpecToCSI translates a volume spec (either PV or inline volume)
// supported by an in-tree plugin to CSI // supported by an in-tree plugin to CSI
func TranslateInTreeSpecToCSI(spec *volume.Spec, podNamespace string, translator InTreeToCSITranslator) (*volume.Spec, error) { func TranslateInTreeSpecToCSI(logger klog.Logger, spec *volume.Spec, podNamespace string, translator InTreeToCSITranslator) (*volume.Spec, error) {
var csiPV *v1.PersistentVolume var csiPV *v1.PersistentVolume
var err error var err error
inlineVolume := false inlineVolume := false
if spec.PersistentVolume != nil { if spec.PersistentVolume != nil {
csiPV, err = translator.TranslateInTreePVToCSI(spec.PersistentVolume) csiPV, err = translator.TranslateInTreePVToCSI(logger, spec.PersistentVolume)
} else if spec.Volume != nil { } else if spec.Volume != nil {
csiPV, err = translator.TranslateInTreeInlineVolumeToCSI(spec.Volume, podNamespace) csiPV, err = translator.TranslateInTreeInlineVolumeToCSI(logger, spec.Volume, podNamespace)
inlineVolume = true inlineVolume = true
} else { } else {
err = errors.New("not a valid volume spec") err = errors.New("not a valid volume spec")

View File

@ -63,8 +63,8 @@ type InTreeToCSITranslator interface {
IsMigratableIntreePluginByName(inTreePluginName string) bool IsMigratableIntreePluginByName(inTreePluginName string) bool
GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error) GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error)
GetCSINameFromInTreeName(pluginName string) (string, error) GetCSINameFromInTreeName(pluginName string) (string, error)
TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error)
TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error)
} }
var _ OperationGenerator = &operationGenerator{} var _ OperationGenerator = &operationGenerator{}

View File

@ -27,6 +27,7 @@ import (
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
) )
const ( const (
@ -57,7 +58,7 @@ func NewAWSElasticBlockStoreCSITranslator() InTreePlugin {
} }
// TranslateInTreeStorageClassToCSI translates InTree EBS storage class parameters to CSI storage class // TranslateInTreeStorageClassToCSI translates InTree EBS storage class parameters to CSI storage class
func (t *awsElasticBlockStoreCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.StorageClass) (*storage.StorageClass, error) { func (t *awsElasticBlockStoreCSITranslator) TranslateInTreeStorageClassToCSI(logger klog.Logger, sc *storage.StorageClass) (*storage.StorageClass, error) {
var ( var (
generatedTopologies []v1.TopologySelectorTerm generatedTopologies []v1.TopologySelectorTerm
params = map[string]string{} params = map[string]string{}
@ -100,7 +101,7 @@ func (t *awsElasticBlockStoreCSITranslator) TranslateInTreeStorageClassToCSI(sc
// TranslateInTreeInlineVolumeToCSI takes a Volume with AWSElasticBlockStore set from in-tree // TranslateInTreeInlineVolumeToCSI takes a Volume with AWSElasticBlockStore set from in-tree
// and converts the AWSElasticBlockStore source to a CSIPersistentVolumeSource // and converts the AWSElasticBlockStore source to a CSIPersistentVolumeSource
func (t *awsElasticBlockStoreCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) { func (t *awsElasticBlockStoreCSITranslator) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) {
if volume == nil || volume.AWSElasticBlockStore == nil { if volume == nil || volume.AWSElasticBlockStore == nil {
return nil, fmt.Errorf("volume is nil or AWS EBS not defined on volume") return nil, fmt.Errorf("volume is nil or AWS EBS not defined on volume")
} }
@ -135,7 +136,7 @@ func (t *awsElasticBlockStoreCSITranslator) TranslateInTreeInlineVolumeToCSI(vol
// TranslateInTreePVToCSI takes a PV with AWSElasticBlockStore set from in-tree // TranslateInTreePVToCSI takes a PV with AWSElasticBlockStore set from in-tree
// and converts the AWSElasticBlockStore source to a CSIPersistentVolumeSource // and converts the AWSElasticBlockStore source to a CSIPersistentVolumeSource
func (t *awsElasticBlockStoreCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { func (t *awsElasticBlockStoreCSITranslator) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if pv == nil || pv.Spec.AWSElasticBlockStore == nil { if pv == nil || pv.Spec.AWSElasticBlockStore == nil {
return nil, fmt.Errorf("pv is nil or AWS EBS not defined on pv") return nil, fmt.Errorf("pv is nil or AWS EBS not defined on pv")
} }

View File

@ -23,6 +23,9 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
"k8s.io/klog/v2/ktesting"
_ "k8s.io/klog/v2/ktesting/init"
) )
const ( const (
@ -79,6 +82,7 @@ func TestKubernetesVolumeIDToEBSVolumeID(t *testing.T) {
func TestTranslateEBSInTreeStorageClassToCSI(t *testing.T) { func TestTranslateEBSInTreeStorageClassToCSI(t *testing.T) {
translator := NewAWSElasticBlockStoreCSITranslator() translator := NewAWSElasticBlockStoreCSITranslator()
logger, _ := ktesting.NewTestContext(t)
cases := []struct { cases := []struct {
name string name string
@ -111,7 +115,7 @@ func TestTranslateEBSInTreeStorageClassToCSI(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreeStorageClassToCSI(tc.sc) got, err := translator.TranslateInTreeStorageClassToCSI(logger, tc.sc)
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }
@ -129,6 +133,7 @@ func TestTranslateEBSInTreeStorageClassToCSI(t *testing.T) {
func TestTranslateInTreeInlineVolumeToCSI(t *testing.T) { func TestTranslateInTreeInlineVolumeToCSI(t *testing.T) {
translator := NewAWSElasticBlockStoreCSITranslator() translator := NewAWSElasticBlockStoreCSITranslator()
logger, _ := ktesting.NewTestContext(t)
cases := []struct { cases := []struct {
name string name string
@ -182,7 +187,7 @@ func TestTranslateInTreeInlineVolumeToCSI(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreeInlineVolumeToCSI(&v1.Volume{Name: "volume", VolumeSource: tc.volumeSource}, "") got, err := translator.TranslateInTreeInlineVolumeToCSI(logger, &v1.Volume{Name: "volume", VolumeSource: tc.volumeSource}, "")
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Fatalf("Did not expect error but got: %v", err) t.Fatalf("Did not expect error but got: %v", err)
} }

View File

@ -24,6 +24,7 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
) )
const ( const (
@ -60,7 +61,7 @@ func NewAzureDiskCSITranslator() InTreePlugin {
} }
// TranslateInTreeStorageClassToCSI translates InTree Azure Disk storage class parameters to CSI storage class // TranslateInTreeStorageClassToCSI translates InTree Azure Disk storage class parameters to CSI storage class
func (t *azureDiskCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.StorageClass) (*storage.StorageClass, error) { func (t *azureDiskCSITranslator) TranslateInTreeStorageClassToCSI(logger klog.Logger, sc *storage.StorageClass) (*storage.StorageClass, error) {
var ( var (
generatedTopologies []v1.TopologySelectorTerm generatedTopologies []v1.TopologySelectorTerm
params = map[string]string{} params = map[string]string{}
@ -96,7 +97,7 @@ func (t *azureDiskCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.St
// TranslateInTreeInlineVolumeToCSI takes a Volume with AzureDisk set from in-tree // TranslateInTreeInlineVolumeToCSI takes a Volume with AzureDisk set from in-tree
// and converts the AzureDisk source to a CSIPersistentVolumeSource // and converts the AzureDisk source to a CSIPersistentVolumeSource
func (t *azureDiskCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) { func (t *azureDiskCSITranslator) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) {
if volume == nil || volume.AzureDisk == nil { if volume == nil || volume.AzureDisk == nil {
return nil, fmt.Errorf("volume is nil or Azure Disk not defined on volume") return nil, fmt.Errorf("volume is nil or Azure Disk not defined on volume")
} }
@ -140,7 +141,7 @@ func (t *azureDiskCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Vol
// TranslateInTreePVToCSI takes a PV with AzureDisk set from in-tree // TranslateInTreePVToCSI takes a PV with AzureDisk set from in-tree
// and converts the AzureDisk source to a CSIPersistentVolumeSource // and converts the AzureDisk source to a CSIPersistentVolumeSource
func (t *azureDiskCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { func (t *azureDiskCSITranslator) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if pv == nil || pv.Spec.AzureDisk == nil { if pv == nil || pv.Spec.AzureDisk == nil {
return nil, fmt.Errorf("pv is nil or Azure Disk source not defined on pv") return nil, fmt.Errorf("pv is nil or Azure Disk source not defined on pv")
} }

View File

@ -24,6 +24,8 @@ import (
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2/ktesting"
_ "k8s.io/klog/v2/ktesting/init"
) )
func TestIsManagedDisk(t *testing.T) { func TestIsManagedDisk(t *testing.T) {
@ -99,6 +101,7 @@ func TestGetDiskName(t *testing.T) {
func TestTranslateAzureDiskInTreeInlineVolumeToCSI(t *testing.T) { func TestTranslateAzureDiskInTreeInlineVolumeToCSI(t *testing.T) {
sharedBlobDiskKind := corev1.AzureDedicatedBlobDisk sharedBlobDiskKind := corev1.AzureDedicatedBlobDisk
translator := NewAzureDiskCSITranslator() translator := NewAzureDiskCSITranslator()
logger, _ := ktesting.NewTestContext(t)
cases := []struct { cases := []struct {
name string name string
@ -158,7 +161,7 @@ func TestTranslateAzureDiskInTreeInlineVolumeToCSI(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreeInlineVolumeToCSI(tc.volume, "") got, err := translator.TranslateInTreeInlineVolumeToCSI(logger, tc.volume, "")
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }
@ -175,6 +178,7 @@ func TestTranslateAzureDiskInTreeInlineVolumeToCSI(t *testing.T) {
func TestTranslateAzureDiskInTreePVToCSI(t *testing.T) { func TestTranslateAzureDiskInTreePVToCSI(t *testing.T) {
translator := NewAzureDiskCSITranslator() translator := NewAzureDiskCSITranslator()
logger, _ := ktesting.NewTestContext(t)
sharedBlobDiskKind := corev1.AzureDedicatedBlobDisk sharedBlobDiskKind := corev1.AzureDedicatedBlobDisk
cachingMode := corev1.AzureDataDiskCachingMode("cachingmode") cachingMode := corev1.AzureDataDiskCachingMode("cachingmode")
@ -250,7 +254,7 @@ func TestTranslateAzureDiskInTreePVToCSI(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreePVToCSI(tc.volume) got, err := translator.TranslateInTreePVToCSI(logger, tc.volume)
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }
@ -447,6 +451,7 @@ func TestTranslateTranslateCSIPVToInTree(t *testing.T) {
func TestTranslateInTreeStorageClassToCSI(t *testing.T) { func TestTranslateInTreeStorageClassToCSI(t *testing.T) {
translator := NewAzureDiskCSITranslator() translator := NewAzureDiskCSITranslator()
logger, _ := ktesting.NewTestContext(t)
tcs := []struct { tcs := []struct {
name string name string
@ -513,7 +518,7 @@ func TestTranslateInTreeStorageClassToCSI(t *testing.T) {
for _, tc := range tcs { for _, tc := range tcs {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
gotOptions, err := translator.TranslateInTreeStorageClassToCSI(tc.options) gotOptions, err := translator.TranslateInTreeStorageClassToCSI(logger, tc.options)
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }

View File

@ -59,13 +59,13 @@ func NewAzureFileCSITranslator() InTreePlugin {
} }
// TranslateInTreeStorageClassToCSI translates InTree Azure File storage class parameters to CSI storage class // TranslateInTreeStorageClassToCSI translates InTree Azure File storage class parameters to CSI storage class
func (t *azureFileCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.StorageClass) (*storage.StorageClass, error) { func (t *azureFileCSITranslator) TranslateInTreeStorageClassToCSI(logger klog.Logger, sc *storage.StorageClass) (*storage.StorageClass, error) {
return sc, nil return sc, nil
} }
// TranslateInTreeInlineVolumeToCSI takes a Volume with AzureFile set from in-tree // TranslateInTreeInlineVolumeToCSI takes a Volume with AzureFile set from in-tree
// and converts the AzureFile source to a CSIPersistentVolumeSource // and converts the AzureFile source to a CSIPersistentVolumeSource
func (t *azureFileCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) { func (t *azureFileCSITranslator) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) {
if volume == nil || volume.AzureFile == nil { if volume == nil || volume.AzureFile == nil {
return nil, fmt.Errorf("volume is nil or Azure File not defined on volume") return nil, fmt.Errorf("volume is nil or Azure File not defined on volume")
} }
@ -73,7 +73,7 @@ func (t *azureFileCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Vol
azureSource := volume.AzureFile azureSource := volume.AzureFile
accountName, err := getStorageAccountName(azureSource.SecretName) accountName, err := getStorageAccountName(azureSource.SecretName)
if err != nil { if err != nil {
klog.V(5).Infof("getStorageAccountName(%s) returned with error: %v", azureSource.SecretName, err) logger.V(5).Info("getStorageAccountName returned with error", "secretName", azureSource.SecretName, "err", err)
accountName = azureSource.SecretName accountName = azureSource.SecretName
} }
@ -112,7 +112,7 @@ func (t *azureFileCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Vol
// TranslateInTreePVToCSI takes a PV with AzureFile set from in-tree // TranslateInTreePVToCSI takes a PV with AzureFile set from in-tree
// and converts the AzureFile source to a CSIPersistentVolumeSource // and converts the AzureFile source to a CSIPersistentVolumeSource
func (t *azureFileCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { func (t *azureFileCSITranslator) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if pv == nil || pv.Spec.AzureFile == nil { if pv == nil || pv.Spec.AzureFile == nil {
return nil, fmt.Errorf("pv is nil or Azure File source not defined on pv") return nil, fmt.Errorf("pv is nil or Azure File source not defined on pv")
} }
@ -120,7 +120,7 @@ func (t *azureFileCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume)
azureSource := pv.Spec.PersistentVolumeSource.AzureFile azureSource := pv.Spec.PersistentVolumeSource.AzureFile
accountName, err := getStorageAccountName(azureSource.SecretName) accountName, err := getStorageAccountName(azureSource.SecretName)
if err != nil { if err != nil {
klog.V(5).Infof("getStorageAccountName(%s) returned with error: %v", azureSource.SecretName, err) logger.V(5).Info("getStorageAccountName returned with error", "secretName", azureSource.SecretName, "err", err)
accountName = azureSource.SecretName accountName = azureSource.SecretName
} }
resourceGroup := "" resourceGroup := ""

View File

@ -23,6 +23,8 @@ import (
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2/ktesting"
_ "k8s.io/klog/v2/ktesting/init"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -100,6 +102,7 @@ func TestGetFileShareInfo(t *testing.T) {
func TestTranslateAzureFileInTreeStorageClassToCSI(t *testing.T) { func TestTranslateAzureFileInTreeStorageClassToCSI(t *testing.T) {
translator := NewAzureFileCSITranslator() translator := NewAzureFileCSITranslator()
logger, _ := ktesting.NewTestContext(t)
cases := []struct { cases := []struct {
name string name string
@ -188,7 +191,7 @@ func TestTranslateAzureFileInTreeStorageClassToCSI(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreeInlineVolumeToCSI(tc.volume, tc.podNamespace) got, err := translator.TranslateInTreeInlineVolumeToCSI(logger, tc.volume, tc.podNamespace)
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }
@ -205,6 +208,7 @@ func TestTranslateAzureFileInTreeStorageClassToCSI(t *testing.T) {
func TestTranslateAzureFileInTreePVToCSI(t *testing.T) { func TestTranslateAzureFileInTreePVToCSI(t *testing.T) {
translator := NewAzureFileCSITranslator() translator := NewAzureFileCSITranslator()
logger, _ := ktesting.NewTestContext(t)
secretNamespace := "secretnamespace" secretNamespace := "secretnamespace"
@ -367,7 +371,7 @@ func TestTranslateAzureFileInTreePVToCSI(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreePVToCSI(tc.volume) got, err := translator.TranslateInTreePVToCSI(logger, tc.volume)
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }

View File

@ -25,6 +25,7 @@ import (
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
) )
const ( const (
@ -78,7 +79,7 @@ func generateToplogySelectors(key string, values []string) []v1.TopologySelector
} }
// TranslateInTreeStorageClassToCSI translates InTree GCE storage class parameters to CSI storage class // TranslateInTreeStorageClassToCSI translates InTree GCE storage class parameters to CSI storage class
func (g *gcePersistentDiskCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.StorageClass) (*storage.StorageClass, error) { func (g *gcePersistentDiskCSITranslator) TranslateInTreeStorageClassToCSI(logger klog.Logger, sc *storage.StorageClass) (*storage.StorageClass, error) {
var generatedTopologies []v1.TopologySelectorTerm var generatedTopologies []v1.TopologySelectorTerm
np := map[string]string{} np := map[string]string{}
@ -162,7 +163,7 @@ func backwardCompatibleAccessModes(ams []v1.PersistentVolumeAccessMode) []v1.Per
// TranslateInTreeInlineVolumeToCSI takes a Volume with GCEPersistentDisk set from in-tree // TranslateInTreeInlineVolumeToCSI takes a Volume with GCEPersistentDisk set from in-tree
// and converts the GCEPersistentDisk source to a CSIPersistentVolumeSource // and converts the GCEPersistentDisk source to a CSIPersistentVolumeSource
func (g *gcePersistentDiskCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) { func (g *gcePersistentDiskCSITranslator) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) {
if volume == nil || volume.GCEPersistentDisk == nil { if volume == nil || volume.GCEPersistentDisk == nil {
return nil, fmt.Errorf("volume is nil or GCE PD not defined on volume") return nil, fmt.Errorf("volume is nil or GCE PD not defined on volume")
} }
@ -208,7 +209,7 @@ func (g *gcePersistentDiskCSITranslator) TranslateInTreeInlineVolumeToCSI(volume
// TranslateInTreePVToCSI takes a PV with GCEPersistentDisk set from in-tree // TranslateInTreePVToCSI takes a PV with GCEPersistentDisk set from in-tree
// and converts the GCEPersistentDisk source to a CSIPersistentVolumeSource // and converts the GCEPersistentDisk source to a CSIPersistentVolumeSource
func (g *gcePersistentDiskCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { func (g *gcePersistentDiskCSITranslator) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
var volID string var volID string
if pv == nil || pv.Spec.GCEPersistentDisk == nil { if pv == nil || pv.Spec.GCEPersistentDisk == nil {

View File

@ -24,6 +24,8 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2/ktesting"
_ "k8s.io/klog/v2/ktesting/init"
) )
func NewStorageClass(params map[string]string, allowedTopologies []v1.TopologySelectorTerm) *storage.StorageClass { func NewStorageClass(params map[string]string, allowedTopologies []v1.TopologySelectorTerm) *storage.StorageClass {
@ -35,6 +37,7 @@ func NewStorageClass(params map[string]string, allowedTopologies []v1.TopologySe
func TestTranslatePDInTreeStorageClassToCSI(t *testing.T) { func TestTranslatePDInTreeStorageClassToCSI(t *testing.T) {
g := NewGCEPersistentDiskCSITranslator() g := NewGCEPersistentDiskCSITranslator()
logger, _ := ktesting.NewTestContext(t)
tcs := []struct { tcs := []struct {
name string name string
@ -86,7 +89,7 @@ func TestTranslatePDInTreeStorageClassToCSI(t *testing.T) {
for _, tc := range tcs { for _, tc := range tcs {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
gotOptions, err := g.TranslateInTreeStorageClassToCSI(tc.options) gotOptions, err := g.TranslateInTreeStorageClassToCSI(logger, tc.options)
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }
@ -266,7 +269,8 @@ func TestBackwardCompatibleAccessModes(t *testing.T) {
func TestInlineReadOnly(t *testing.T) { func TestInlineReadOnly(t *testing.T) {
g := NewGCEPersistentDiskCSITranslator() g := NewGCEPersistentDiskCSITranslator()
pv, err := g.TranslateInTreeInlineVolumeToCSI(&v1.Volume{ logger, _ := ktesting.NewTestContext(t)
pv, err := g.TranslateInTreeInlineVolumeToCSI(logger, &v1.Volume{
VolumeSource: v1.VolumeSource{ VolumeSource: v1.VolumeSource{
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
PDName: "foo", PDName: "foo",
@ -298,6 +302,7 @@ func TestInlineReadOnly(t *testing.T) {
func TestTranslateInTreePVToCSIVolIDFmt(t *testing.T) { func TestTranslateInTreePVToCSIVolIDFmt(t *testing.T) {
g := NewGCEPersistentDiskCSITranslator() g := NewGCEPersistentDiskCSITranslator()
logger, _ := ktesting.NewTestContext(t)
pdName := "pd-name" pdName := "pd-name"
tests := []struct { tests := []struct {
desc string desc string
@ -332,7 +337,7 @@ func TestTranslateInTreePVToCSIVolIDFmt(t *testing.T) {
} }
for _, tc := range tests { for _, tc := range tests {
t.Run(tc.desc, func(t *testing.T) { t.Run(tc.desc, func(t *testing.T) {
translatedPV, err := g.TranslateInTreePVToCSI(&v1.PersistentVolume{ translatedPV, err := g.TranslateInTreePVToCSI(logger, &v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{tc.topologyLabelKey: tc.topologyLabelValue}, Labels: map[string]string{tc.topologyLabelKey: tc.topologyLabelValue},
}, },

View File

@ -25,6 +25,7 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
) )
// InTreePlugin handles translations between CSI and in-tree sources in a PV // InTreePlugin handles translations between CSI and in-tree sources in a PV
@ -32,17 +33,17 @@ type InTreePlugin interface {
// TranslateInTreeStorageClassToCSI takes in-tree volume options // TranslateInTreeStorageClassToCSI takes in-tree volume options
// and translates them to a volume options consumable by CSI plugin // and translates them to a volume options consumable by CSI plugin
TranslateInTreeStorageClassToCSI(sc *storage.StorageClass) (*storage.StorageClass, error) TranslateInTreeStorageClassToCSI(logger klog.Logger, sc *storage.StorageClass) (*storage.StorageClass, error)
// TranslateInTreeInlineVolumeToCSI takes a inline volume and will translate // TranslateInTreeInlineVolumeToCSI takes a inline volume and will translate
// the in-tree inline volume source to a CSIPersistentVolumeSource // the in-tree inline volume source to a CSIPersistentVolumeSource
// A PV object containing the CSIPersistentVolumeSource in it's spec is returned // A PV object containing the CSIPersistentVolumeSource in it's spec is returned
// podNamespace is only needed for azurefile to fetch secret namespace, no need to be set for other plugins. // podNamespace is only needed for azurefile to fetch secret namespace, no need to be set for other plugins.
TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error)
// TranslateInTreePVToCSI takes a persistent volume and will translate // TranslateInTreePVToCSI takes a persistent volume and will translate
// the in-tree pv source to a CSI Source. The input persistent volume can be modified // the in-tree pv source to a CSI Source. The input persistent volume can be modified
TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error)
// TranslateCSIPVToInTree takes a PV with a CSI PersistentVolume Source and will translate // TranslateCSIPVToInTree takes a PV with a CSI PersistentVolume Source and will translate
// it to a in-tree Persistent Volume Source for the in-tree volume // it to a in-tree Persistent Volume Source for the in-tree volume

View File

@ -23,6 +23,7 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
) )
const ( const (
@ -45,7 +46,7 @@ func NewOpenStackCinderCSITranslator() InTreePlugin {
} }
// TranslateInTreeStorageClassToCSI translates InTree Cinder storage class parameters to CSI storage class // TranslateInTreeStorageClassToCSI translates InTree Cinder storage class parameters to CSI storage class
func (t *osCinderCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.StorageClass) (*storage.StorageClass, error) { func (t *osCinderCSITranslator) TranslateInTreeStorageClassToCSI(logger klog.Logger, sc *storage.StorageClass) (*storage.StorageClass, error) {
var ( var (
params = map[string]string{} params = map[string]string{}
) )
@ -75,7 +76,7 @@ func (t *osCinderCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.Sto
// TranslateInTreeInlineVolumeToCSI takes a Volume with Cinder set from in-tree // TranslateInTreeInlineVolumeToCSI takes a Volume with Cinder set from in-tree
// and converts the Cinder source to a CSIPersistentVolumeSource // and converts the Cinder source to a CSIPersistentVolumeSource
func (t *osCinderCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) { func (t *osCinderCSITranslator) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) {
if volume == nil || volume.Cinder == nil { if volume == nil || volume.Cinder == nil {
return nil, fmt.Errorf("volume is nil or Cinder not defined on volume") return nil, fmt.Errorf("volume is nil or Cinder not defined on volume")
} }
@ -105,7 +106,7 @@ func (t *osCinderCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volu
// TranslateInTreePVToCSI takes a PV with Cinder set from in-tree // TranslateInTreePVToCSI takes a PV with Cinder set from in-tree
// and converts the Cinder source to a CSIPersistentVolumeSource // and converts the Cinder source to a CSIPersistentVolumeSource
func (t *osCinderCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { func (t *osCinderCSITranslator) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if pv == nil || pv.Spec.Cinder == nil { if pv == nil || pv.Spec.Cinder == nil {
return nil, fmt.Errorf("pv is nil or Cinder not defined on pv") return nil, fmt.Errorf("pv is nil or Cinder not defined on pv")
} }

View File

@ -22,10 +22,13 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
"k8s.io/klog/v2/ktesting"
_ "k8s.io/klog/v2/ktesting/init"
) )
func TestTranslateCinderInTreeStorageClassToCSI(t *testing.T) { func TestTranslateCinderInTreeStorageClassToCSI(t *testing.T) {
translator := NewOpenStackCinderCSITranslator() translator := NewOpenStackCinderCSITranslator()
logger, _ := ktesting.NewTestContext(t)
cases := []struct { cases := []struct {
name string name string
@ -63,7 +66,7 @@ func TestTranslateCinderInTreeStorageClassToCSI(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreeStorageClassToCSI(tc.sc) got, err := translator.TranslateInTreeStorageClassToCSI(logger, tc.sc)
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }

View File

@ -19,9 +19,10 @@ package plugins
import ( import (
"fmt" "fmt"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1" storagev1 "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
) )
const ( const (
@ -39,7 +40,7 @@ func NewPortworxCSITranslator() InTreePlugin {
// TranslateInTreeStorageClassToCSI takes in-tree storage class used by in-tree plugin // TranslateInTreeStorageClassToCSI takes in-tree storage class used by in-tree plugin
// and translates them to a storageclass consumable by CSI plugin // and translates them to a storageclass consumable by CSI plugin
func (p portworxCSITranslator) TranslateInTreeStorageClassToCSI(sc *storagev1.StorageClass) (*storagev1.StorageClass, error) { func (p portworxCSITranslator) TranslateInTreeStorageClassToCSI(logger klog.Logger, sc *storagev1.StorageClass) (*storagev1.StorageClass, error) {
if sc == nil { if sc == nil {
return nil, fmt.Errorf("sc is nil") return nil, fmt.Errorf("sc is nil")
} }
@ -49,7 +50,7 @@ func (p portworxCSITranslator) TranslateInTreeStorageClassToCSI(sc *storagev1.St
// TranslateInTreeInlineVolumeToCSI takes a inline volume and will translate // TranslateInTreeInlineVolumeToCSI takes a inline volume and will translate
// the in-tree inline volume source to a CSIPersistentVolumeSource // the in-tree inline volume source to a CSIPersistentVolumeSource
func (p portworxCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) { func (p portworxCSITranslator) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) {
if volume == nil || volume.PortworxVolume == nil { if volume == nil || volume.PortworxVolume == nil {
return nil, fmt.Errorf("volume is nil or PortworxVolume not defined on volume") return nil, fmt.Errorf("volume is nil or PortworxVolume not defined on volume")
} }
@ -82,7 +83,7 @@ func (p portworxCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volum
// TranslateInTreePVToCSI takes a Portworx persistent volume and will translate // TranslateInTreePVToCSI takes a Portworx persistent volume and will translate
// the in-tree pv source to a CSI Source // the in-tree pv source to a CSI Source
func (p portworxCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { func (p portworxCSITranslator) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if pv == nil || pv.Spec.PortworxVolume == nil { if pv == nil || pv.Spec.PortworxVolume == nil {
return nil, fmt.Errorf("pv is nil or PortworxVolume not defined on pv") return nil, fmt.Errorf("pv is nil or PortworxVolume not defined on pv")
} }

View File

@ -17,15 +17,19 @@ limitations under the License.
package plugins package plugins
import ( import (
"reflect"
"testing"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"reflect" "k8s.io/klog/v2/ktesting"
"testing" _ "k8s.io/klog/v2/ktesting/init"
) )
func TestTranslatePortworxInTreeStorageClassToCSI(t *testing.T) { func TestTranslatePortworxInTreeStorageClassToCSI(t *testing.T) {
translator := NewPortworxCSITranslator() translator := NewPortworxCSITranslator()
logger, _ := ktesting.NewTestContext(t)
testCases := []struct { testCases := []struct {
name string name string
inTreeSC *storage.StorageClass inTreeSC *storage.StorageClass
@ -71,7 +75,7 @@ func TestTranslatePortworxInTreeStorageClassToCSI(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
result, err := translator.TranslateInTreeStorageClassToCSI(tc.inTreeSC) result, err := translator.TranslateInTreeStorageClassToCSI(logger, tc.inTreeSC)
if err != nil && !tc.errorExp { if err != nil && !tc.errorExp {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }
@ -86,6 +90,8 @@ func TestTranslatePortworxInTreeStorageClassToCSI(t *testing.T) {
func TestTranslatePortworxInTreeInlineVolumeToCSI(t *testing.T) { func TestTranslatePortworxInTreeInlineVolumeToCSI(t *testing.T) {
translator := NewPortworxCSITranslator() translator := NewPortworxCSITranslator()
logger, _ := ktesting.NewTestContext(t)
testCases := []struct { testCases := []struct {
name string name string
inLine *v1.Volume inLine *v1.Volume
@ -136,7 +142,7 @@ func TestTranslatePortworxInTreeInlineVolumeToCSI(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
result, err := translator.TranslateInTreeInlineVolumeToCSI(tc.inLine, "ns") result, err := translator.TranslateInTreeInlineVolumeToCSI(logger, tc.inLine, "ns")
if err != nil && !tc.errExpected { if err != nil && !tc.errExpected {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }
@ -151,6 +157,7 @@ func TestTranslatePortworxInTreeInlineVolumeToCSI(t *testing.T) {
func TestTranslatePortworxInTreePVToCSI(t *testing.T) { func TestTranslatePortworxInTreePVToCSI(t *testing.T) {
translator := NewPortworxCSITranslator() translator := NewPortworxCSITranslator()
logger, _ := ktesting.NewTestContext(t)
testCases := []struct { testCases := []struct {
name string name string
@ -234,7 +241,7 @@ func TestTranslatePortworxInTreePVToCSI(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
result, err := translator.TranslateInTreePVToCSI(tc.inTree) result, err := translator.TranslateInTreePVToCSI(logger, tc.inTree)
if err != nil && !tc.errExpected { if err != nil && !tc.errExpected {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }

View File

@ -74,7 +74,7 @@ func NewvSphereCSITranslator() InTreePlugin {
} }
// TranslateInTreeStorageClassToCSI translates InTree vSphere storage class parameters to CSI storage class // TranslateInTreeStorageClassToCSI translates InTree vSphere storage class parameters to CSI storage class
func (t *vSphereCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.StorageClass) (*storage.StorageClass, error) { func (t *vSphereCSITranslator) TranslateInTreeStorageClassToCSI(logger klog.Logger, sc *storage.StorageClass) (*storage.StorageClass, error) {
if sc == nil { if sc == nil {
return nil, fmt.Errorf("sc is nil") return nil, fmt.Errorf("sc is nil")
} }
@ -102,7 +102,7 @@ func (t *vSphereCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.Stor
case "iopslimit": case "iopslimit":
params[paramIopslimit] = v params[paramIopslimit] = v
default: default:
klog.V(2).Infof("StorageClass parameter [name:%q, value:%q] is not supported", k, v) logger.V(2).Info("StorageClass parameter is not supported", "name", k, "value", v)
} }
} }
@ -124,7 +124,7 @@ func (t *vSphereCSITranslator) TranslateInTreeStorageClassToCSI(sc *storage.Stor
// TranslateInTreeInlineVolumeToCSI takes a Volume with VsphereVolume set from in-tree // TranslateInTreeInlineVolumeToCSI takes a Volume with VsphereVolume set from in-tree
// and converts the VsphereVolume source to a CSIPersistentVolumeSource // and converts the VsphereVolume source to a CSIPersistentVolumeSource
func (t *vSphereCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) { func (t *vSphereCSITranslator) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) {
if volume == nil || volume.VsphereVolume == nil { if volume == nil || volume.VsphereVolume == nil {
return nil, fmt.Errorf("volume is nil or VsphereVolume not defined on volume") return nil, fmt.Errorf("volume is nil or VsphereVolume not defined on volume")
} }
@ -154,7 +154,7 @@ func (t *vSphereCSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volum
// TranslateInTreePVToCSI takes a PV with VsphereVolume set from in-tree // TranslateInTreePVToCSI takes a PV with VsphereVolume set from in-tree
// and converts the VsphereVolume source to a CSIPersistentVolumeSource // and converts the VsphereVolume source to a CSIPersistentVolumeSource
func (t *vSphereCSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { func (t *vSphereCSITranslator) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if pv == nil || pv.Spec.VsphereVolume == nil { if pv == nil || pv.Spec.VsphereVolume == nil {
return nil, fmt.Errorf("pv is nil or VsphereVolume not defined on pv") return nil, fmt.Errorf("pv is nil or VsphereVolume not defined on pv")
} }

View File

@ -24,10 +24,13 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2/ktesting"
_ "k8s.io/klog/v2/ktesting/init"
) )
func TestTranslatevSphereInTreeStorageClassToCSI(t *testing.T) { func TestTranslatevSphereInTreeStorageClassToCSI(t *testing.T) {
translator := NewvSphereCSITranslator() translator := NewvSphereCSITranslator()
logger, _ := ktesting.NewTestContext(t)
topologySelectorTerm := v1.TopologySelectorTerm{MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{ topologySelectorTerm := v1.TopologySelectorTerm{MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
{ {
Key: v1.LabelTopologyZone, Key: v1.LabelTopologyZone,
@ -111,7 +114,7 @@ func TestTranslatevSphereInTreeStorageClassToCSI(t *testing.T) {
} }
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreeStorageClassToCSI(tc.sc) got, err := translator.TranslateInTreeStorageClassToCSI(logger, tc.sc)
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }
@ -291,6 +294,7 @@ func TestTranslateVSphereCSIPVToInTree(t *testing.T) {
func TestTranslateVSphereInTreePVToCSI(t *testing.T) { func TestTranslateVSphereInTreePVToCSI(t *testing.T) {
translator := NewvSphereCSITranslator() translator := NewvSphereCSITranslator()
logger, _ := ktesting.NewTestContext(t)
cases := []struct { cases := []struct {
name string name string
intreePV *v1.PersistentVolume intreePV *v1.PersistentVolume
@ -462,7 +466,7 @@ func TestTranslateVSphereInTreePVToCSI(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreePVToCSI(tc.intreePV) got, err := translator.TranslateInTreePVToCSI(logger, tc.intreePV)
if err != nil && !tc.expErr { if err != nil && !tc.expErr {
t.Errorf("Did not expect error but got: %v", err) t.Errorf("Did not expect error but got: %v", err)
} }
@ -479,6 +483,7 @@ func TestTranslateVSphereInTreePVToCSI(t *testing.T) {
func TestTranslatevSphereInTreeInlineVolumeToCSI(t *testing.T) { func TestTranslatevSphereInTreeInlineVolumeToCSI(t *testing.T) {
translator := NewvSphereCSITranslator() translator := NewvSphereCSITranslator()
logger, _ := ktesting.NewTestContext(t)
cases := []struct { cases := []struct {
name string name string
inlinevolume *v1.Volume inlinevolume *v1.Volume
@ -523,7 +528,7 @@ func TestTranslatevSphereInTreeInlineVolumeToCSI(t *testing.T) {
for _, tc := range cases { for _, tc := range cases {
t.Logf("Testing %v", tc.name) t.Logf("Testing %v", tc.name)
got, err := translator.TranslateInTreeInlineVolumeToCSI(tc.inlinevolume, "") got, err := translator.TranslateInTreeInlineVolumeToCSI(logger, tc.inlinevolume, "")
if err == nil && tc.expErr { if err == nil && tc.expErr {
t.Errorf("Expected error, but did not get one.") t.Errorf("Expected error, but did not get one.")
continue continue

View File

@ -23,6 +23,7 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1" storage "k8s.io/api/storage/v1"
"k8s.io/csi-translation-lib/plugins" "k8s.io/csi-translation-lib/plugins"
"k8s.io/klog/v2"
) )
var ( var (
@ -50,11 +51,11 @@ func New() CSITranslator {
// TranslateInTreeStorageClassToCSI takes in-tree Storage Class // TranslateInTreeStorageClassToCSI takes in-tree Storage Class
// and translates it to a set of parameters consumable by CSI plugin // and translates it to a set of parameters consumable by CSI plugin
func (CSITranslator) TranslateInTreeStorageClassToCSI(inTreePluginName string, sc *storage.StorageClass) (*storage.StorageClass, error) { func (CSITranslator) TranslateInTreeStorageClassToCSI(logger klog.Logger, inTreePluginName string, sc *storage.StorageClass) (*storage.StorageClass, error) {
newSC := sc.DeepCopy() newSC := sc.DeepCopy()
for _, curPlugin := range inTreePlugins { for _, curPlugin := range inTreePlugins {
if inTreePluginName == curPlugin.GetInTreePluginName() { if inTreePluginName == curPlugin.GetInTreePluginName() {
return curPlugin.TranslateInTreeStorageClassToCSI(newSC) return curPlugin.TranslateInTreeStorageClassToCSI(logger, newSC)
} }
} }
return nil, fmt.Errorf("could not find in-tree storage class parameter translation logic for %#v", inTreePluginName) return nil, fmt.Errorf("could not find in-tree storage class parameter translation logic for %#v", inTreePluginName)
@ -63,13 +64,13 @@ func (CSITranslator) TranslateInTreeStorageClassToCSI(inTreePluginName string, s
// TranslateInTreeInlineVolumeToCSI takes a inline volume and will translate // TranslateInTreeInlineVolumeToCSI takes a inline volume and will translate
// the in-tree volume source to a CSIPersistentVolumeSource (wrapped in a PV) // the in-tree volume source to a CSIPersistentVolumeSource (wrapped in a PV)
// if the translation logic has been implemented. // if the translation logic has been implemented.
func (CSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) { func (CSITranslator) TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) {
if volume == nil { if volume == nil {
return nil, fmt.Errorf("persistent volume was nil") return nil, fmt.Errorf("persistent volume was nil")
} }
for _, curPlugin := range inTreePlugins { for _, curPlugin := range inTreePlugins {
if curPlugin.CanSupportInline(volume) { if curPlugin.CanSupportInline(volume) {
pv, err := curPlugin.TranslateInTreeInlineVolumeToCSI(volume, podNamespace) pv, err := curPlugin.TranslateInTreeInlineVolumeToCSI(logger, volume, podNamespace)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -92,14 +93,14 @@ func (CSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume, podName
// the in-tree source to a CSI Source if the translation logic // the in-tree source to a CSI Source if the translation logic
// has been implemented. The input persistent volume will not // has been implemented. The input persistent volume will not
// be modified // be modified
func (CSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) { func (CSITranslator) TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if pv == nil { if pv == nil {
return nil, errors.New("persistent volume was nil") return nil, errors.New("persistent volume was nil")
} }
copiedPV := pv.DeepCopy() copiedPV := pv.DeepCopy()
for _, curPlugin := range inTreePlugins { for _, curPlugin := range inTreePlugins {
if curPlugin.CanSupport(copiedPV) { if curPlugin.CanSupport(copiedPV) {
return curPlugin.TranslateInTreePVToCSI(copiedPV) return curPlugin.TranslateInTreePVToCSI(logger, copiedPV)
} }
} }
return nil, fmt.Errorf("could not find in-tree plugin translation logic for %#v", copiedPV.Name) return nil, fmt.Errorf("could not find in-tree plugin translation logic for %#v", copiedPV.Name)

View File

@ -25,6 +25,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/uuid" "k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/csi-translation-lib/plugins" "k8s.io/csi-translation-lib/plugins"
"k8s.io/klog/v2/ktesting"
_ "k8s.io/klog/v2/ktesting/init"
) )
var ( var (
@ -45,6 +47,7 @@ var (
) )
func TestTranslationStability(t *testing.T) { func TestTranslationStability(t *testing.T) {
logger, _ := ktesting.NewTestContext(t)
testCases := []struct { testCases := []struct {
name string name string
pv *v1.PersistentVolume pv *v1.PersistentVolume
@ -84,7 +87,7 @@ func TestTranslationStability(t *testing.T) {
for _, test := range testCases { for _, test := range testCases {
ctl := New() ctl := New()
t.Logf("Testing %v", test.name) t.Logf("Testing %v", test.name)
csiSource, err := ctl.TranslateInTreePVToCSI(test.pv) csiSource, err := ctl.TranslateInTreePVToCSI(logger, test.pv)
if err != nil { if err != nil {
t.Errorf("Error when translating to CSI: %v", err) t.Errorf("Error when translating to CSI: %v", err)
} }
@ -99,6 +102,7 @@ func TestTranslationStability(t *testing.T) {
} }
func TestTopologyTranslation(t *testing.T) { func TestTopologyTranslation(t *testing.T) {
logger, _ := ktesting.NewTestContext(t)
testCases := []struct { testCases := []struct {
name string name string
key string key string
@ -207,7 +211,7 @@ func TestTopologyTranslation(t *testing.T) {
t.Logf("Testing %v", test.name) t.Logf("Testing %v", test.name)
// Translate to CSI PV and check translated node affinity // Translate to CSI PV and check translated node affinity
newCSIPV, err := ctl.TranslateInTreePVToCSI(test.pv) newCSIPV, err := ctl.TranslateInTreePVToCSI(logger, test.pv)
if err != nil { if err != nil {
t.Errorf("Error when translating to CSI: %v", err) t.Errorf("Error when translating to CSI: %v", err)
} }
@ -365,12 +369,13 @@ func makeTopology(key string, values ...string) *v1.NodeSelectorRequirement {
func TestTranslateInTreeInlineVolumeToCSINameUniqueness(t *testing.T) { func TestTranslateInTreeInlineVolumeToCSINameUniqueness(t *testing.T) {
for driverName := range inTreePlugins { for driverName := range inTreePlugins {
t.Run(driverName, func(t *testing.T) { t.Run(driverName, func(t *testing.T) {
logger, _ := ktesting.NewTestContext(t)
ctl := New() ctl := New()
vs1, err := generateUniqueVolumeSource(driverName) vs1, err := generateUniqueVolumeSource(driverName)
if err != nil { if err != nil {
t.Fatalf("Couldn't generate random source: %v", err) t.Fatalf("Couldn't generate random source: %v", err)
} }
pv1, err := ctl.TranslateInTreeInlineVolumeToCSI(&v1.Volume{ pv1, err := ctl.TranslateInTreeInlineVolumeToCSI(logger, &v1.Volume{
VolumeSource: vs1, VolumeSource: vs1,
}, "") }, "")
if err != nil { if err != nil {
@ -380,7 +385,7 @@ func TestTranslateInTreeInlineVolumeToCSINameUniqueness(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Couldn't generate random source: %v", err) t.Fatalf("Couldn't generate random source: %v", err)
} }
pv2, err := ctl.TranslateInTreeInlineVolumeToCSI(&v1.Volume{ pv2, err := ctl.TranslateInTreeInlineVolumeToCSI(logger, &v1.Volume{
VolumeSource: vs2, VolumeSource: vs2,
}, "") }, "")
if err != nil { if err != nil {