Merge pull request #82683 from davidz627/fix/translationStruct

Refactor CSI Translation Library into a struct that is injected into various components to simplify unit testing
This commit is contained in:
Kubernetes Prow Robot 2019-09-29 10:11:37 -07:00 committed by GitHub
commit 14e5adfc85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 168 additions and 94 deletions

View File

@ -141,6 +141,7 @@ go_library(
"//staging/src/k8s.io/component-base/cli/globalflag:go_default_library",
"//staging/src/k8s.io/component-base/version:go_default_library",
"//staging/src/k8s.io/component-base/version/verflag:go_default_library",
"//staging/src/k8s.io/csi-translation-lib:go_default_library",
"//staging/src/k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1:go_default_library",
"//staging/src/k8s.io/metrics/pkg/client/custom_metrics:go_default_library",
"//staging/src/k8s.io/metrics/pkg/client/external_metrics:go_default_library",

View File

@ -36,6 +36,7 @@ import (
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/metadata"
restclient "k8s.io/client-go/rest"
csitrans "k8s.io/csi-translation-lib"
"k8s.io/kubernetes/pkg/controller"
cloudcontroller "k8s.io/kubernetes/pkg/controller/cloud"
endpointcontroller "k8s.io/kubernetes/pkg/controller/endpoint"
@ -309,7 +310,8 @@ func startVolumeExpandController(ctx ControllerContext) (http.Handler, bool, err
ctx.InformerFactory.Core().V1().PersistentVolumes(),
ctx.InformerFactory.Storage().V1().StorageClasses(),
ctx.Cloud,
ProbeExpandableVolumePlugins(ctx.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration))
ProbeExpandableVolumePlugins(ctx.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration),
csitrans.New())
if expandControllerErr != nil {
return nil, true, fmt.Errorf("failed to start volume expand controller : %v", expandControllerErr)

View File

@ -32,7 +32,6 @@ go_library(
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/client-go/util/workqueue:go_default_library",
"//staging/src/k8s.io/cloud-provider:go_default_library",
"//staging/src/k8s.io/csi-translation-lib:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
)
@ -75,6 +74,7 @@ go_test(
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//staging/src/k8s.io/csi-translation-lib:go_default_library",
"//staging/src/k8s.io/csi-translation-lib/plugins:go_default_library",
],
)

View File

@ -41,7 +41,6 @@ import (
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
cloudprovider "k8s.io/cloud-provider"
csitranslation "k8s.io/csi-translation-lib"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/controller/volume/events"
"k8s.io/kubernetes/pkg/util/mount"
@ -62,6 +61,11 @@ type ExpandController interface {
Run(stopCh <-chan struct{})
}
// CSINameTranslator can get the CSI Driver name based on the in-tree plugin name
type CSINameTranslator interface {
GetCSINameFromInTreeName(pluginName string) (string, error)
}
type expandController struct {
// kubeClient is the kube API client used by volumehost to communicate with
// the API server.
@ -92,6 +96,8 @@ type expandController struct {
operationGenerator operationexecutor.OperationGenerator
queue workqueue.RateLimitingInterface
translator CSINameTranslator
}
// NewExpandController expands the pvs
@ -101,7 +107,8 @@ func NewExpandController(
pvInformer coreinformers.PersistentVolumeInformer,
scInformer storageclassinformer.StorageClassInformer,
cloud cloudprovider.Interface,
plugins []volume.VolumePlugin) (ExpandController, error) {
plugins []volume.VolumePlugin,
translator CSINameTranslator) (ExpandController, error) {
expc := &expandController{
kubeClient: kubeClient,
@ -113,6 +120,7 @@ func NewExpandController(
classLister: scInformer.Lister(),
classListerSynced: scInformer.Informer().HasSynced,
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "volume_expand"),
translator: translator,
}
if err := expc.volumePluginMgr.InitPlugins(plugins, nil, expc); err != nil {
@ -255,7 +263,7 @@ func (expc *expandController) syncHandler(key string) error {
if volumePlugin.IsMigratedToCSI() {
msg := fmt.Sprintf("CSI migration enabled for %s; waiting for external resizer to expand the pvc", volumeResizerName)
expc.recorder.Event(pvc, v1.EventTypeNormal, events.ExternalExpanding, msg)
csiResizerName, err := csitranslation.GetCSINameFromInTreeName(class.Provisioner)
csiResizerName, err := expc.translator.GetCSINameFromInTreeName(class.Provisioner)
if err != nil {
errorMsg := fmt.Sprintf("error getting CSI driver name for pvc %s, with error %v", util.ClaimToClaimKey(pvc), err)
expc.recorder.Event(pvc, v1.EventTypeWarning, events.ExternalExpanding, errorMsg)

View File

@ -33,6 +33,7 @@ import (
"k8s.io/client-go/informers"
coretesting "k8s.io/client-go/testing"
featuregatetesting "k8s.io/component-base/featuregate/testing"
csitrans "k8s.io/csi-translation-lib"
csitranslationplugins "k8s.io/csi-translation-lib/plugins"
"k8s.io/kubernetes/pkg/controller"
controllervolumetesting "k8s.io/kubernetes/pkg/controller/volume/attachdetach/testing"
@ -123,7 +124,7 @@ func TestSyncHandler(t *testing.T) {
if tc.storageClass != nil {
informerFactory.Storage().V1().StorageClasses().Informer().GetIndexer().Add(tc.storageClass)
}
expc, err := NewExpandController(fakeKubeClient, pvcInformer, pvInformer, storageClassInformer, nil, allPlugins)
expc, err := NewExpandController(fakeKubeClient, pvcInformer, pvInformer, storageClassInformer, nil, allPlugins, csitrans.New())
if err != nil {
t.Fatalf("error creating expand controller : %v", err)
}

View File

@ -101,6 +101,7 @@ go_test(
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/client-go/tools/reference:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//staging/src/k8s.io/csi-translation-lib:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
)

View File

@ -521,6 +521,12 @@ func wrapTestWithProvisionCalls(expectedProvisionCalls []provisionCall, toWrap t
return wrapTestWithPluginCalls(nil, nil, expectedProvisionCalls, toWrap)
}
type fakeCSINameTranslator struct{}
func (t fakeCSINameTranslator) GetCSINameFromInTreeName(pluginName string) (string, error) {
return "vendor.com/MockCSIPlugin", nil
}
// wrapTestWithCSIMigrationProvisionCalls returns a testCall that:
// - configures controller with a volume plugin that emulates CSI migration
// - calls given testCall
@ -530,9 +536,7 @@ func wrapTestWithCSIMigrationProvisionCalls(toWrap testCall) testCall {
isMigratedToCSI: true,
}
ctrl.volumePluginMgr.InitPlugins([]vol.VolumePlugin{plugin}, nil /* prober */, ctrl)
ctrl.csiNameFromIntreeNameHook = func(string) (string, error) {
return "vendor.com/MockCSIPlugin", nil
}
ctrl.translator = fakeCSINameTranslator{}
return toWrap(ctrl, reactor, test)
}
}

View File

@ -39,7 +39,6 @@ import (
"k8s.io/client-go/util/workqueue"
cloudprovider "k8s.io/cloud-provider"
volerr "k8s.io/cloud-provider/volume/errors"
csitranslation "k8s.io/csi-translation-lib"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/controller/volume/events"
"k8s.io/kubernetes/pkg/controller/volume/persistentvolume/metrics"
@ -134,6 +133,11 @@ const createProvisionedPVRetryCount = 5
// Interval between retries when we create a PV object for a provisioned volume.
const createProvisionedPVInterval = 10 * time.Second
// CSINameTranslator can get the CSI Driver name based on the in-tree plugin name
type CSINameTranslator interface {
GetCSINameFromInTreeName(pluginName string) (string, error)
}
// PersistentVolumeController is a controller that synchronizes
// PersistentVolumeClaims and PersistentVolumes. It starts two
// cache.Controllers that watch PersistentVolume and PersistentVolumeClaim
@ -200,10 +204,6 @@ type PersistentVolumeController struct {
createProvisionedPVRetryCount int
createProvisionedPVInterval time.Duration
// For testing only: hook to intercept CSI driver name <=> Intree plugin name mapping
// Not used when set to nil
csiNameFromIntreeNameHook func(pluginName string) (string, error)
// operationTimestamps caches start timestamp of operations
// (currently provision + binding/deletion) for metric recording.
// Detailed lifecyle/key for each operation
@ -225,6 +225,8 @@ type PersistentVolumeController struct {
// the corresponding timestamp entry will be deleted from cache
// abort: N.A.
operationTimestamps metrics.OperationStartTimeCache
translator CSINameTranslator
}
// syncClaim is the main controller method to decide what to do with a claim.
@ -1355,13 +1357,6 @@ func (ctrl *PersistentVolumeController) provisionClaim(claim *v1.PersistentVolum
return nil
}
func (ctrl *PersistentVolumeController) getCSINameFromIntreeName(pluginName string) (string, error) {
if ctrl.csiNameFromIntreeNameHook != nil {
return ctrl.csiNameFromIntreeNameHook(pluginName)
}
return csitranslation.GetCSINameFromInTreeName(pluginName)
}
// provisionClaimOperation provisions a volume. This method is running in
// standalone goroutine and already has all necessary locks.
func (ctrl *PersistentVolumeController) provisionClaimOperation(
@ -1571,7 +1566,7 @@ func (ctrl *PersistentVolumeController) provisionClaimOperationExternal(
provisionerName := storageClass.Provisioner
if plugin != nil {
// update the provisioner name to use the CSI in-tree name
provisionerName, err = ctrl.getCSINameFromIntreeName(storageClass.Provisioner)
provisionerName, err = ctrl.translator.GetCSINameFromInTreeName(storageClass.Provisioner)
if err != nil {
strerr := fmt.Sprintf("error getting CSI name for In tree plugin %s: %v", storageClass.Provisioner, err)
klog.V(2).Infof("%s", strerr)
@ -1732,7 +1727,7 @@ func (ctrl *PersistentVolumeController) getProvisionerNameFromVolume(volume *v1.
return "N/A"
}
if plugin != nil {
provisionerName, err := ctrl.getCSINameFromIntreeName(class.Provisioner)
provisionerName, err := ctrl.translator.GetCSINameFromInTreeName(class.Provisioner)
if err == nil {
return provisionerName
}
@ -1747,7 +1742,7 @@ func (ctrl *PersistentVolumeController) getProvisionerName(plugin vol.Provisiona
return plugin.GetPluginName()
} else if plugin != nil {
// get the CSI in-tree name from storage class provisioner name
provisionerName, err := ctrl.getCSINameFromIntreeName(storageClass.Provisioner)
provisionerName, err := ctrl.translator.GetCSINameFromInTreeName(storageClass.Provisioner)
if err != nil {
return "N/A"
}

View File

@ -38,6 +38,7 @@ import (
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
cloudprovider "k8s.io/cloud-provider"
csitrans "k8s.io/csi-translation-lib"
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/controller/volume/persistentvolume/metrics"
pvutil "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/util"
@ -93,6 +94,7 @@ func NewController(p ControllerParameters) (*PersistentVolumeController, error)
volumeQueue: workqueue.NewNamed("volumes"),
resyncPeriod: p.SyncPeriod,
operationTimestamps: metrics.NewOperationStartTimeCache(),
translator: csitrans.New(),
}
// Prober is nil because PV is not aware of Flexvolume.

View File

@ -30,6 +30,7 @@ import (
storagelisters "k8s.io/client-go/listers/storage/v1"
core "k8s.io/client-go/testing"
"k8s.io/client-go/tools/cache"
csitrans "k8s.io/csi-translation-lib"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/controller"
pvtesting "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/testing"
@ -438,6 +439,7 @@ func TestDelayBindingMode(t *testing.T) {
classInformer := informerFactory.Storage().V1().StorageClasses()
ctrl := &PersistentVolumeController{
classLister: classInformer.Lister(),
translator: csitrans.New(),
}
for _, class := range classes {

View File

@ -23,7 +23,7 @@ import (
storagev1beta1 "k8s.io/api/storage/v1beta1"
"k8s.io/apimachinery/pkg/util/rand"
utilfeature "k8s.io/apiserver/pkg/util/feature"
csilib "k8s.io/csi-translation-lib"
csitrans "k8s.io/csi-translation-lib"
"k8s.io/klog"
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
"k8s.io/kubernetes/pkg/features"
@ -31,6 +31,16 @@ import (
volumeutil "k8s.io/kubernetes/pkg/volume/util"
)
// InTreeToCSITranslator contains methods required to check migratable status
// and perform translations from InTree PV's to CSI
type InTreeToCSITranslator interface {
IsPVMigratable(pv *v1.PersistentVolume) bool
IsMigratableIntreePluginByName(inTreePluginName string) bool
GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error)
GetCSINameFromInTreeName(pluginName string) (string, error)
TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error)
}
// CSIMaxVolumeLimitChecker defines predicate needed for counting CSI volumes
type CSIMaxVolumeLimitChecker struct {
csiNodeInfo CSINodeInfo
@ -39,6 +49,8 @@ type CSIMaxVolumeLimitChecker struct {
scInfo StorageClassInfo
randomVolumeIDPrefix string
translator InTreeToCSITranslator
}
// NewCSIMaxVolumeLimitPredicate returns a predicate for counting CSI volumes
@ -50,6 +62,7 @@ func NewCSIMaxVolumeLimitPredicate(
pvcInfo: pvcInfo,
scInfo: scInfo,
randomVolumeIDPrefix: rand.String(32),
translator: csitrans.New(),
}
return c.attachableLimitPredicate
}
@ -201,11 +214,11 @@ func (c *CSIMaxVolumeLimitChecker) getCSIDriverInfo(csiNode *storagev1beta1.CSIN
csiSource := pv.Spec.PersistentVolumeSource.CSI
if csiSource == nil {
// We make a fast path for non-CSI volumes that aren't migratable
if !csilib.IsPVMigratable(pv) {
if !c.translator.IsPVMigratable(pv) {
return "", ""
}
pluginName, err := csilib.GetInTreePluginNameFromSpec(pv, nil)
pluginName, err := c.translator.GetInTreePluginNameFromSpec(pv, nil)
if err != nil {
klog.V(5).Infof("Unable to look up plugin name from PV spec: %v", err)
return "", ""
@ -216,7 +229,7 @@ func (c *CSIMaxVolumeLimitChecker) getCSIDriverInfo(csiNode *storagev1beta1.CSIN
return "", ""
}
csiPV, err := csilib.TranslateInTreePVToCSI(pv)
csiPV, err := c.translator.TranslateInTreePVToCSI(pv)
if err != nil {
klog.V(5).Infof("Unable to translate in-tree volume to CSI: %v", err)
return "", ""
@ -258,13 +271,13 @@ func (c *CSIMaxVolumeLimitChecker) getCSIDriverInfoFromSC(csiNode *storagev1beta
volumeHandle := fmt.Sprintf("%s-%s/%s", c.randomVolumeIDPrefix, namespace, pvcName)
provisioner := storageClass.Provisioner
if csilib.IsMigratableIntreePluginByName(provisioner) {
if c.translator.IsMigratableIntreePluginByName(provisioner) {
if !isCSIMigrationOn(csiNode, provisioner) {
klog.V(5).Infof("CSI Migration of plugin %s is not enabled", provisioner)
return "", ""
}
driverName, err := csilib.GetCSINameFromInTreeName(provisioner)
driverName, err := c.translator.GetCSINameFromInTreeName(provisioner)
if err != nil {
klog.V(5).Infof("Unable to look up driver name from plugin name: %v", err)
return "", ""

View File

@ -67,6 +67,7 @@ go_test(
"//staging/src/k8s.io/component-base/featuregate:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",
"//staging/src/k8s.io/csi-translation-lib:go_default_library",
"//staging/src/k8s.io/csi-translation-lib/plugins:go_default_library",
"//vendor/github.com/prometheus/client_model/go:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",

View File

@ -21,6 +21,7 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
csitrans "k8s.io/csi-translation-lib"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
@ -88,6 +89,10 @@ func (f *fakeOGCounter) GetVolumePluginMgr() *volume.VolumePluginMgr {
return nil
}
func (f *fakeOGCounter) GetCSITranslator() InTreeToCSITranslator {
return csitrans.New()
}
func (f *fakeOGCounter) GenerateBulkVolumeVerifyFunc(
map[types.NodeName][]*volume.Spec,
string,

View File

@ -641,14 +641,14 @@ func (oe *operationExecutor) VerifyVolumesAreAttached(
}
// Migration: Must also check the Node since Attach would have been done with in-tree if node is not using Migration
nu, err := nodeUsingCSIPlugin(oe.operationGenerator, volumeAttached.VolumeSpec, node)
nu, err := nodeUsingCSIPlugin(oe.operationGenerator.GetCSITranslator(), oe.operationGenerator.GetVolumePluginMgr(), volumeAttached.VolumeSpec, node)
if err != nil {
klog.Errorf(volumeAttached.GenerateErrorDetailed("VolumesAreAttached.NodeUsingCSIPlugin failed", err).Error())
continue
}
var volumePlugin volume.VolumePlugin
if useCSIPlugin(oe.operationGenerator.GetVolumePluginMgr(), volumeAttached.VolumeSpec) && nu {
if useCSIPlugin(oe.operationGenerator.GetCSITranslator(), oe.operationGenerator.GetVolumePluginMgr(), volumeAttached.VolumeSpec) && nu {
// The volume represented by this spec is CSI and thus should be migrated
volumePlugin, err = oe.operationGenerator.GetVolumePluginMgr().FindPluginByName(csi.CSIPluginName)
if err != nil || volumePlugin == nil {
@ -661,7 +661,7 @@ func (oe *operationExecutor) VerifyVolumesAreAttached(
continue
}
csiSpec, err := translateSpec(volumeAttached.VolumeSpec)
csiSpec, err := translateSpec(oe.operationGenerator.GetCSITranslator(), volumeAttached.VolumeSpec)
if err != nil {
klog.Errorf(volumeAttached.GenerateErrorDetailed("VolumesAreAttached.TranslateSpec failed", err).Error())
continue

View File

@ -25,6 +25,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/uuid"
csitrans "k8s.io/csi-translation-lib"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/hostutil"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
@ -520,6 +521,10 @@ func (fopg *fakeOperationGenerator) GetVolumePluginMgr() *volume.VolumePluginMgr
return nil
}
func (fopg *fakeOperationGenerator) GetCSITranslator() InTreeToCSITranslator {
return csitrans.New()
}
func getTestPodWithSecret(podName, secretName string) *v1.Pod {
return &v1.Pod{
ObjectMeta: metav1.ObjectMeta{

View File

@ -32,7 +32,7 @@ import (
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/record"
volerr "k8s.io/cloud-provider/volume/errors"
csilib "k8s.io/csi-translation-lib"
csitrans "k8s.io/csi-translation-lib"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/features"
kevents "k8s.io/kubernetes/pkg/kubelet/events"
@ -49,6 +49,18 @@ const (
unknownAttachableVolumePlugin string = "UnknownAttachableVolumePlugin"
)
// InTreeToCSITranslator contains methods required to check migratable status
// and perform translations from InTree PVs and Inline to CSI
type InTreeToCSITranslator interface {
IsPVMigratable(pv *v1.PersistentVolume) bool
IsInlineMigratable(vol *v1.Volume) bool
IsMigratableIntreePluginByName(inTreePluginName string) bool
GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error)
GetCSINameFromInTreeName(pluginName string) (string, error)
TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error)
TranslateInTreeInlineVolumeToCSI(volume *v1.Volume) (*v1.PersistentVolume, error)
}
var _ OperationGenerator = &operationGenerator{}
type operationGenerator struct {
@ -70,6 +82,8 @@ type operationGenerator struct {
// blkUtil provides volume path related operations for block volume
blkUtil volumepathhandler.BlockVolumePathHandler
translator InTreeToCSITranslator
}
// NewOperationGenerator is returns instance of operationGenerator
@ -85,6 +99,7 @@ func NewOperationGenerator(kubeClient clientset.Interface,
recorder: recorder,
checkNodeCapabilitiesBeforeMount: checkNodeCapabilitiesBeforeMount,
blkUtil: blkUtil,
translator: csitrans.New(),
}
}
@ -123,6 +138,9 @@ type OperationGenerator interface {
// GetVolumePluginMgr returns volume plugin manager
GetVolumePluginMgr() *volume.VolumePluginMgr
// GetCSITranslator returns the CSI Translation Library
GetCSITranslator() InTreeToCSITranslator
GenerateBulkVolumeVerifyFunc(
map[types.NodeName][]*volume.Spec,
string,
@ -153,14 +171,14 @@ func (og *operationGenerator) GenerateVolumesAreAttachedFunc(
}
// Migration: Must also check the Node since Attach would have been done with in-tree if node is not using Migration
nu, err := nodeUsingCSIPlugin(og, volumeAttached.VolumeSpec, nodeName)
nu, err := nodeUsingCSIPlugin(og.translator, og.volumePluginMgr, volumeAttached.VolumeSpec, nodeName)
if err != nil {
klog.Errorf(volumeAttached.GenerateErrorDetailed("VolumesAreAttached.NodeUsingCSIPlugin failed", err).Error())
continue
}
var volumePlugin volume.VolumePlugin
if useCSIPlugin(og.volumePluginMgr, volumeAttached.VolumeSpec) && nu {
if useCSIPlugin(og.translator, og.volumePluginMgr, volumeAttached.VolumeSpec) && nu {
// The volume represented by this spec is CSI and thus should be migrated
volumePlugin, err = og.volumePluginMgr.FindPluginByName(csi.CSIPluginName)
if err != nil || volumePlugin == nil {
@ -168,7 +186,7 @@ func (og *operationGenerator) GenerateVolumesAreAttachedFunc(
continue
}
csiSpec, err := translateSpec(volumeAttached.VolumeSpec)
csiSpec, err := translateSpec(og.translator, volumeAttached.VolumeSpec)
if err != nil {
klog.Errorf(volumeAttached.GenerateErrorDetailed("VolumesAreAttached.TranslateSpec failed", err).Error())
continue
@ -330,20 +348,20 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
attachVolumeFunc := func() (error, error) {
var attachableVolumePlugin volume.AttachableVolumePlugin
nu, err := nodeUsingCSIPlugin(og, volumeToAttach.VolumeSpec, volumeToAttach.NodeName)
nu, err := nodeUsingCSIPlugin(og.translator, og.volumePluginMgr, volumeToAttach.VolumeSpec, volumeToAttach.NodeName)
if err != nil {
return volumeToAttach.GenerateError("AttachVolume.NodeUsingCSIPlugin failed", err)
}
// useCSIPlugin will check both CSIMigration and the plugin specific feature gates
if useCSIPlugin(og.volumePluginMgr, volumeToAttach.VolumeSpec) && nu {
if useCSIPlugin(og.translator, og.volumePluginMgr, volumeToAttach.VolumeSpec) && nu {
// The volume represented by this spec is CSI and thus should be migrated
attachableVolumePlugin, err = og.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
if err != nil || attachableVolumePlugin == nil {
return volumeToAttach.GenerateError("AttachVolume.FindAttachablePluginByName failed", err)
}
csiSpec, err := translateSpec(volumeToAttach.VolumeSpec)
csiSpec, err := translateSpec(og.translator, volumeToAttach.VolumeSpec)
if err != nil {
return volumeToAttach.GenerateError("AttachVolume.TranslateSpec failed", err)
}
@ -416,15 +434,15 @@ func (og *operationGenerator) GenerateAttachVolumeFunc(
// involves determining the plugin_name for the metric generating "CompleteFunc"
// during the actual "OperationFunc" and not during this generation function
nu, err := nodeUsingCSIPlugin(og, volumeToAttach.VolumeSpec, volumeToAttach.NodeName)
nu, err := nodeUsingCSIPlugin(og.translator, og.volumePluginMgr, volumeToAttach.VolumeSpec, volumeToAttach.NodeName)
if err != nil {
klog.Errorf("GenerateAttachVolumeFunc failed to check if node is using CSI Plugin, metric for this operation may be inaccurate: %v", err)
}
// Need to translate the spec here if the plugin is migrated so that the metrics
// emitted show the correct (migrated) plugin
if useCSIPlugin(og.volumePluginMgr, volumeToAttach.VolumeSpec) && nu {
csiSpec, err := translateSpec(volumeToAttach.VolumeSpec)
if useCSIPlugin(og.translator, og.volumePluginMgr, volumeToAttach.VolumeSpec) && nu {
csiSpec, err := translateSpec(og.translator, volumeToAttach.VolumeSpec)
if err == nil {
volumeToAttach.VolumeSpec = csiSpec
}
@ -456,6 +474,10 @@ func (og *operationGenerator) GetVolumePluginMgr() *volume.VolumePluginMgr {
return og.volumePluginMgr
}
func (og *operationGenerator) GetCSITranslator() InTreeToCSITranslator {
return og.translator
}
func (og *operationGenerator) GenerateDetachVolumeFunc(
volumeToDetach AttachedVolume,
verifySafeToDetach bool,
@ -467,20 +489,20 @@ func (og *operationGenerator) GenerateDetachVolumeFunc(
if volumeToDetach.VolumeSpec != nil {
// Get attacher plugin
nu, err := nodeUsingCSIPlugin(og, volumeToDetach.VolumeSpec, volumeToDetach.NodeName)
nu, err := nodeUsingCSIPlugin(og.translator, og.volumePluginMgr, volumeToDetach.VolumeSpec, volumeToDetach.NodeName)
if err != nil {
return volumetypes.GeneratedOperations{}, volumeToDetach.GenerateErrorDetailed("DetachVolume.NodeUsingCSIPlugin failed", err)
}
// useCSIPlugin will check both CSIMigration and the plugin specific feature gate
if useCSIPlugin(og.volumePluginMgr, volumeToDetach.VolumeSpec) && nu {
if useCSIPlugin(og.translator, og.volumePluginMgr, volumeToDetach.VolumeSpec) && nu {
// The volume represented by this spec is CSI and thus should be migrated
attachableVolumePlugin, err = og.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
if err != nil || attachableVolumePlugin == nil {
return volumetypes.GeneratedOperations{}, volumeToDetach.GenerateErrorDetailed("DetachVolume.FindAttachablePluginBySpec failed", err)
}
csiSpec, err := translateSpec(volumeToDetach.VolumeSpec)
csiSpec, err := translateSpec(og.translator, volumeToDetach.VolumeSpec)
if err != nil {
return volumetypes.GeneratedOperations{}, volumeToDetach.GenerateErrorDetailed("DetachVolume.TranslateSpec failed", err)
}
@ -511,7 +533,7 @@ func (og *operationGenerator) GenerateDetachVolumeFunc(
// TODO(dyzz): This case can't distinguish between PV and In-line which is necessary because
// if it was PV it may have been migrated, but the same plugin with in-line may not have been.
// Suggestions welcome...
if csilib.IsMigratableIntreePluginByName(pluginName) && utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) {
if og.translator.IsMigratableIntreePluginByName(pluginName) && utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) {
// The volume represented by this spec is CSI and thus should be migrated
attachableVolumePlugin, err = og.volumePluginMgr.FindAttachablePluginByName(csi.CSIPluginName)
if err != nil || attachableVolumePlugin == nil {
@ -582,8 +604,8 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
volumePluginName := unknownVolumePlugin
// Need to translate the spec here if the plugin is migrated so that the metrics
// emitted show the correct (migrated) plugin
if useCSIPlugin(og.volumePluginMgr, volumeToMount.VolumeSpec) {
csiSpec, err := translateSpec(volumeToMount.VolumeSpec)
if useCSIPlugin(og.translator, og.volumePluginMgr, volumeToMount.VolumeSpec) {
csiSpec, err := translateSpec(og.translator, volumeToMount.VolumeSpec)
if err == nil {
volumeToMount.VolumeSpec = csiSpec
}
@ -601,8 +623,8 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
mountVolumeFunc := func() (error, error) {
// Get mounter plugin
if useCSIPlugin(og.volumePluginMgr, volumeToMount.VolumeSpec) {
csiSpec, err := translateSpec(volumeToMount.VolumeSpec)
if useCSIPlugin(og.translator, og.volumePluginMgr, volumeToMount.VolumeSpec) {
csiSpec, err := translateSpec(og.translator, volumeToMount.VolumeSpec)
if err != nil {
return volumeToMount.GenerateError("MountVolume.TranslateSpec failed", err)
}
@ -795,7 +817,7 @@ func (og *operationGenerator) GenerateUnmountVolumeFunc(
podsDir string) (volumetypes.GeneratedOperations, error) {
var pluginName string
if volumeToUnmount.VolumeSpec != nil && useCSIPlugin(og.volumePluginMgr, volumeToUnmount.VolumeSpec) {
if volumeToUnmount.VolumeSpec != nil && useCSIPlugin(og.translator, og.volumePluginMgr, volumeToUnmount.VolumeSpec) {
pluginName = csi.CSIPluginName
} else {
pluginName = volumeToUnmount.PluginName
@ -863,9 +885,9 @@ func (og *operationGenerator) GenerateUnmountDeviceFunc(
hostutil hostutil.HostUtils) (volumetypes.GeneratedOperations, error) {
var pluginName string
if useCSIPlugin(og.volumePluginMgr, deviceToDetach.VolumeSpec) {
if useCSIPlugin(og.translator, og.volumePluginMgr, deviceToDetach.VolumeSpec) {
pluginName = csi.CSIPluginName
csiSpec, err := translateSpec(deviceToDetach.VolumeSpec)
csiSpec, err := translateSpec(og.translator, deviceToDetach.VolumeSpec)
if err != nil {
return volumetypes.GeneratedOperations{}, deviceToDetach.GenerateErrorDetailed("UnmountDevice.TranslateSpec failed", err)
}
@ -965,8 +987,8 @@ func (og *operationGenerator) GenerateMapVolumeFunc(
originalSpec := volumeToMount.VolumeSpec
// Translate to CSI spec if migration enabled
if useCSIPlugin(og.volumePluginMgr, originalSpec) {
csiSpec, err := translateSpec(originalSpec)
if useCSIPlugin(og.translator, og.volumePluginMgr, originalSpec) {
csiSpec, err := translateSpec(og.translator, originalSpec)
if err != nil {
return volumetypes.GeneratedOperations{}, volumeToMount.GenerateErrorDetailed("MapVolume.TranslateSpec failed", err)
}
@ -1153,8 +1175,8 @@ func (og *operationGenerator) GenerateUnmapVolumeFunc(
var err error
// Translate to CSI spec if migration enabled
// And get block volume unmapper plugin
if volumeToUnmount.VolumeSpec != nil && useCSIPlugin(og.volumePluginMgr, volumeToUnmount.VolumeSpec) {
csiSpec, err := translateSpec(volumeToUnmount.VolumeSpec)
if volumeToUnmount.VolumeSpec != nil && useCSIPlugin(og.translator, og.volumePluginMgr, volumeToUnmount.VolumeSpec) {
csiSpec, err := translateSpec(og.translator, volumeToUnmount.VolumeSpec)
if err != nil {
return volumetypes.GeneratedOperations{}, volumeToUnmount.GenerateErrorDetailed("UnmapVolume.TranslateSpec failed", err)
}
@ -1249,8 +1271,8 @@ func (og *operationGenerator) GenerateUnmapDeviceFunc(
var blockVolumePlugin volume.BlockVolumePlugin
var err error
// Translate to CSI spec if migration enabled
if useCSIPlugin(og.volumePluginMgr, deviceToDetach.VolumeSpec) {
csiSpec, err := translateSpec(deviceToDetach.VolumeSpec)
if useCSIPlugin(og.translator, og.volumePluginMgr, deviceToDetach.VolumeSpec) {
csiSpec, err := translateSpec(og.translator, deviceToDetach.VolumeSpec)
if err != nil {
return volumetypes.GeneratedOperations{}, deviceToDetach.GenerateErrorDetailed("UnmapDevice.TranslateSpec failed", err)
}
@ -1564,8 +1586,8 @@ func (og *operationGenerator) GenerateExpandInUseVolumeFunc(
fsResizeFunc := func() (error, error) {
// Need to translate the spec here if the plugin is migrated so that the metrics
// emitted show the correct (migrated) plugin
if useCSIPlugin(og.volumePluginMgr, volumeToMount.VolumeSpec) {
csiSpec, err := translateSpec(volumeToMount.VolumeSpec)
if useCSIPlugin(og.translator, og.volumePluginMgr, volumeToMount.VolumeSpec) {
csiSpec, err := translateSpec(og.translator, volumeToMount.VolumeSpec)
if err != nil {
return volumeToMount.GenerateError("NodeExpandVolume.translateSpec failed", err)
}
@ -1636,8 +1658,8 @@ func (og *operationGenerator) GenerateExpandInUseVolumeFunc(
// Need to translate the spec here if the plugin is migrated so that the metrics
// emitted show the correct (migrated) plugin
if useCSIPlugin(og.volumePluginMgr, volumeToMount.VolumeSpec) {
csiSpec, err := translateSpec(volumeToMount.VolumeSpec)
if useCSIPlugin(og.translator, og.volumePluginMgr, volumeToMount.VolumeSpec) {
csiSpec, err := translateSpec(og.translator, volumeToMount.VolumeSpec)
if err == nil {
volumeToMount.VolumeSpec = csiSpec
}
@ -1796,7 +1818,7 @@ func isDeviceOpened(deviceToDetach AttachedVolume, hostUtil hostutil.HostUtils)
return deviceOpened, nil
}
func useCSIPlugin(vpm *volume.VolumePluginMgr, spec *volume.Spec) bool {
func useCSIPlugin(tr InTreeToCSITranslator, vpm *volume.VolumePluginMgr, spec *volume.Spec) bool {
// TODO(#75146) Check whether the driver is installed as well so that
// we can throw a better error when the driver is not installed.
// The error should be of the approximate form:
@ -1804,7 +1826,7 @@ func useCSIPlugin(vpm *volume.VolumePluginMgr, spec *volume.Spec) bool {
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIMigration) {
return false
}
if csilib.IsPVMigratable(spec.PersistentVolume) || csilib.IsInlineMigratable(spec.Volume) {
if tr.IsPVMigratable(spec.PersistentVolume) || tr.IsInlineMigratable(spec.Volume) {
migratable, err := vpm.IsPluginMigratableBySpec(spec)
if err == nil && migratable {
return true
@ -1813,9 +1835,7 @@ func useCSIPlugin(vpm *volume.VolumePluginMgr, spec *volume.Spec) bool {
return false
}
func nodeUsingCSIPlugin(og OperationGenerator, spec *volume.Spec, nodeName types.NodeName) (bool, error) {
vpm := og.GetVolumePluginMgr()
func nodeUsingCSIPlugin(tr InTreeToCSITranslator, vpm *volume.VolumePluginMgr, spec *volume.Spec, nodeName types.NodeName) (bool, error) {
migratable, err := vpm.IsPluginMigratableBySpec(spec)
if err != nil {
return false, err
@ -1869,7 +1889,7 @@ func nodeUsingCSIPlugin(og OperationGenerator, spec *volume.Spec, nodeName types
mpaSet = sets.NewString(tok...)
}
pluginName, err := csilib.GetInTreePluginNameFromSpec(spec.PersistentVolume, spec.Volume)
pluginName, err := tr.GetInTreePluginNameFromSpec(spec.PersistentVolume, spec.Volume)
if err != nil {
return false, err
}
@ -1883,7 +1903,7 @@ func nodeUsingCSIPlugin(og OperationGenerator, spec *volume.Spec, nodeName types
if isMigratedOnNode {
installed := false
driverName, err := csilib.GetCSINameFromInTreeName(pluginName)
driverName, err := tr.GetCSINameFromInTreeName(pluginName)
if err != nil {
return isMigratedOnNode, err
}
@ -1902,19 +1922,19 @@ func nodeUsingCSIPlugin(og OperationGenerator, spec *volume.Spec, nodeName types
}
func translateSpec(spec *volume.Spec) (*volume.Spec, error) {
func translateSpec(tr InTreeToCSITranslator, spec *volume.Spec) (*volume.Spec, error) {
var csiPV *v1.PersistentVolume
var err error
inlineVolume := false
if spec.PersistentVolume != nil {
// TranslateInTreePVToCSI will create a new PV
csiPV, err = csilib.TranslateInTreePVToCSI(spec.PersistentVolume)
csiPV, err = tr.TranslateInTreePVToCSI(spec.PersistentVolume)
if err != nil {
return nil, fmt.Errorf("failed to translate in tree pv to CSI: %v", err)
}
} else if spec.Volume != nil {
// TranslateInTreeInlineVolumeToCSI will create a new PV
csiPV, err = csilib.TranslateInTreeInlineVolumeToCSI(spec.Volume)
csiPV, err = tr.TranslateInTreeInlineVolumeToCSI(spec.Volume)
if err != nil {
return nil, fmt.Errorf("failed to translate in tree inline volume to CSI: %v", err)
}

View File

@ -125,7 +125,7 @@ func TestOperationGenerator_GenerateUnmapVolumeFunc_PluginName(t *testing.T) {
// csi plugin looks a file that contains some information about the volume,
// and GenerateUnmapVolumeFuncfails if csi plugin can't find that file.
// So the reason for calling plugin.NewBlockVolumeMapper for csi enabled case is creating that file.
csiSpec, err := translateSpec(volumeToUnmount.VolumeSpec)
csiSpec, err := translateSpec(operationGenerator.GetCSITranslator(), volumeToUnmount.VolumeSpec)
if err != nil {
t.Fatalf("Can't translate volume to CSI")
}

View File

@ -35,9 +35,20 @@ var (
}
)
// CSITranslator translates in-tree storage API objects to their equivalent CSI
// API objects. It also provides many helper functions to determine whether
// translation logic exists and the mappings between "in-tree plugin <-> csi driver"
type CSITranslator struct{}
// New creates a new CSITranslator which does real translation
// for "in-tree plugins <-> csi drivers"
func New() CSITranslator {
return CSITranslator{}
}
// TranslateInTreeStorageClassToCSI takes in-tree Storage Class
// and translates it to a set of parameters consumable by CSI plugin
func TranslateInTreeStorageClassToCSI(inTreePluginName string, sc *storage.StorageClass) (*storage.StorageClass, error) {
func (ctl CSITranslator) TranslateInTreeStorageClassToCSI(inTreePluginName string, sc *storage.StorageClass) (*storage.StorageClass, error) {
newSC := sc.DeepCopy()
for _, curPlugin := range inTreePlugins {
if inTreePluginName == curPlugin.GetInTreePluginName() {
@ -50,7 +61,7 @@ func TranslateInTreeStorageClassToCSI(inTreePluginName string, sc *storage.Stora
// TranslateInTreeInlineVolumeToCSI takes a inline volume and will translate
// the in-tree volume source to a CSIPersistentVolumeSource (wrapped in a PV)
// if the translation logic has been implemented.
func TranslateInTreeInlineVolumeToCSI(volume *v1.Volume) (*v1.PersistentVolume, error) {
func (ctl CSITranslator) TranslateInTreeInlineVolumeToCSI(volume *v1.Volume) (*v1.PersistentVolume, error) {
if volume == nil {
return nil, fmt.Errorf("persistent volume was nil")
}
@ -66,7 +77,7 @@ func TranslateInTreeInlineVolumeToCSI(volume *v1.Volume) (*v1.PersistentVolume,
// the in-tree source to a CSI Source if the translation logic
// has been implemented. The input persistent volume will not
// be modified
func TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
func (ctl CSITranslator) TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if pv == nil {
return nil, errors.New("persistent volume was nil")
}
@ -82,7 +93,7 @@ func TranslateInTreePVToCSI(pv *v1.PersistentVolume) (*v1.PersistentVolume, erro
// TranslateCSIPVToInTree takes a PV with a CSI PersistentVolume Source and will translate
// it to a in-tree Persistent Volume Source for the specific in-tree volume specified
// by the `Driver` field in the CSI Source. The input PV object will not be modified.
func TranslateCSIPVToInTree(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
func (ctl CSITranslator) TranslateCSIPVToInTree(pv *v1.PersistentVolume) (*v1.PersistentVolume, error) {
if pv == nil || pv.Spec.CSI == nil {
return nil, errors.New("CSI persistent volume was nil")
}
@ -97,7 +108,7 @@ func TranslateCSIPVToInTree(pv *v1.PersistentVolume) (*v1.PersistentVolume, erro
// IsMigratableIntreePluginByName tests whether there is migration logic for the in-tree plugin
// whose name matches the given name
func IsMigratableIntreePluginByName(inTreePluginName string) bool {
func (ctl CSITranslator) IsMigratableIntreePluginByName(inTreePluginName string) bool {
for _, curPlugin := range inTreePlugins {
if curPlugin.GetInTreePluginName() == inTreePluginName {
return true
@ -108,7 +119,7 @@ func IsMigratableIntreePluginByName(inTreePluginName string) bool {
// IsMigratedCSIDriverByName tests whether there exists an in-tree plugin with logic
// to migrate to the CSI driver with given name
func IsMigratedCSIDriverByName(csiPluginName string) bool {
func (ctl CSITranslator) IsMigratedCSIDriverByName(csiPluginName string) bool {
if _, ok := inTreePlugins[csiPluginName]; ok {
return true
}
@ -116,7 +127,7 @@ func IsMigratedCSIDriverByName(csiPluginName string) bool {
}
// GetInTreePluginNameFromSpec returns the plugin name
func GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error) {
func (ctl CSITranslator) GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error) {
if pv != nil {
for _, curPlugin := range inTreePlugins {
if curPlugin.CanSupport(pv) {
@ -138,7 +149,7 @@ func GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (strin
// GetCSINameFromInTreeName returns the name of a CSI driver that supersedes the
// in-tree plugin with the given name
func GetCSINameFromInTreeName(pluginName string) (string, error) {
func (ctl CSITranslator) GetCSINameFromInTreeName(pluginName string) (string, error) {
for csiDriverName, curPlugin := range inTreePlugins {
if curPlugin.GetInTreePluginName() == pluginName {
return csiDriverName, nil
@ -149,7 +160,7 @@ func GetCSINameFromInTreeName(pluginName string) (string, error) {
// GetInTreeNameFromCSIName returns the name of the in-tree plugin superseded by
// a CSI driver with the given name
func GetInTreeNameFromCSIName(pluginName string) (string, error) {
func (ctl CSITranslator) GetInTreeNameFromCSIName(pluginName string) (string, error) {
if plugin, ok := inTreePlugins[pluginName]; ok {
return plugin.GetInTreePluginName(), nil
}
@ -157,7 +168,7 @@ func GetInTreeNameFromCSIName(pluginName string) (string, error) {
}
// IsPVMigratable tests whether there is migration logic for the given Persistent Volume
func IsPVMigratable(pv *v1.PersistentVolume) bool {
func (ctl CSITranslator) IsPVMigratable(pv *v1.PersistentVolume) bool {
for _, curPlugin := range inTreePlugins {
if curPlugin.CanSupport(pv) {
return true
@ -167,7 +178,7 @@ func IsPVMigratable(pv *v1.PersistentVolume) bool {
}
// IsInlineMigratable tests whether there is Migration logic for the given Inline Volume
func IsInlineMigratable(vol *v1.Volume) bool {
func (ctl CSITranslator) IsInlineMigratable(vol *v1.Volume) bool {
for _, curPlugin := range inTreePlugins {
if curPlugin.CanSupportInline(vol) {
return true

View File

@ -61,12 +61,13 @@ func TestTranslationStability(t *testing.T) {
},
}
for _, test := range testCases {
ctl := New()
t.Logf("Testing %v", test.name)
csiSource, err := TranslateInTreePVToCSI(test.pv)
csiSource, err := ctl.TranslateInTreePVToCSI(test.pv)
if err != nil {
t.Errorf("Error when translating to CSI: %v", err)
}
newPV, err := TranslateCSIPVToInTree(csiSource)
newPV, err := ctl.TranslateCSIPVToInTree(csiSource)
if err != nil {
t.Errorf("Error when translating CSI Source to in tree volume: %v", err)
}
@ -95,18 +96,19 @@ func TestPluginNameMappings(t *testing.T) {
}
for _, test := range testCases {
t.Logf("Testing %v", test.name)
csiPluginName, err := GetCSINameFromInTreeName(test.inTreePluginName)
ctl := New()
csiPluginName, err := ctl.GetCSINameFromInTreeName(test.inTreePluginName)
if err != nil {
t.Errorf("Error when mapping In-tree plugin name to CSI plugin name %s", err)
}
if !IsMigratedCSIDriverByName(csiPluginName) {
if !ctl.IsMigratedCSIDriverByName(csiPluginName) {
t.Errorf("%s expected to supersede an In-tree plugin", csiPluginName)
}
inTreePluginName, err := GetInTreeNameFromCSIName(csiPluginName)
inTreePluginName, err := ctl.GetInTreeNameFromCSIName(csiPluginName)
if err != nil {
t.Errorf("Error when mapping CSI plugin name to In-tree plugin name %s", err)
}
if !IsMigratableIntreePluginByName(inTreePluginName) {
if !ctl.IsMigratableIntreePluginByName(inTreePluginName) {
t.Errorf("%s expected to be migratable to a CSI name", inTreePluginName)
}
if inTreePluginName != test.inTreePluginName || csiPluginName != test.csiPluginName {

View File

@ -34,7 +34,7 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
clientset "k8s.io/client-go/kubernetes"
csilib "k8s.io/csi-translation-lib"
csitrans "k8s.io/csi-translation-lib"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/framework/metrics"
"k8s.io/kubernetes/test/e2e/framework/podlogs"
@ -558,7 +558,8 @@ func addOpCounts(o1 opCounts, o2 opCounts) opCounts {
func getMigrationVolumeOpCounts(cs clientset.Interface, pluginName string) (opCounts, opCounts) {
if len(pluginName) > 0 {
var migratedOps opCounts
csiName, err := csilib.GetCSINameFromInTreeName(pluginName)
l := csitrans.New()
csiName, err := l.GetCSINameFromInTreeName(pluginName)
if err != nil {
framework.Logf("Could not find CSI Name for in-tree plugin %v", pluginName)
migratedOps = opCounts{}