From c6c74d684606c269a741a0daf1c0a0e8e439cea3 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 28 Aug 2018 15:01:39 +0200 Subject: [PATCH] Skip attach for non-attachable CSI volumes --- pkg/volume/csi/csi_attacher.go | 45 ++++++++++++++++++++++---------- pkg/volume/csi/csi_mounter.go | 16 ++---------- pkg/volume/csi/csi_plugin.go | 47 ++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 27 deletions(-) diff --git a/pkg/volume/csi/csi_attacher.go b/pkg/volume/csi/csi_attacher.go index 1b33926e9f6..963fda0d09c 100644 --- a/pkg/volume/csi/csi_attacher.go +++ b/pkg/volume/csi/csi_attacher.go @@ -70,6 +70,16 @@ func (c *csiAttacher) Attach(spec *volume.Spec, nodeName types.NodeName) (string return "", err } + skip, err := c.plugin.skipAttach(csiSource.Driver) + if err != nil { + glog.Error(log("attacher.Attach failed to find if driver is attachable: %v", err)) + return "", err + } + if skip { + glog.V(4).Infof(log("skipping attach for driver %s", csiSource.Driver)) + return "", nil + } + node := string(nodeName) pvName := spec.PersistentVolume.GetName() attachID := getAttachmentName(csiSource.VolumeHandle, csiSource.Driver, node) @@ -120,6 +130,16 @@ func (c *csiAttacher) WaitForAttach(spec *volume.Spec, attachID string, pod *v1. return "", err } + skip, err := c.plugin.skipAttach(source.Driver) + if err != nil { + glog.Error(log("attacher.Attach failed to find if driver is attachable: %v", err)) + return "", err + } + if skip { + glog.V(4).Infof(log("Driver is not attachable, skip waiting for attach")) + return "", nil + } + return c.waitForVolumeAttachment(source.VolumeHandle, attachID, timeout) } @@ -221,11 +241,22 @@ func (c *csiAttacher) VolumesAreAttached(specs []*volume.Spec, nodeName types.No glog.Error(log("attacher.VolumesAreAttached failed: %v", err)) continue } + skip, err := c.plugin.skipAttach(source.Driver) + if err != nil { + glog.Error(log("Failed to check CSIDriver for %s: %s", source.Driver, err)) + } else { + if skip { + // This volume is not attachable, pretend it's attached + attached[spec] = true + continue + } + } attachID := getAttachmentName(source.VolumeHandle, source.Driver, string(nodeName)) glog.V(4).Info(log("probing attachment status for VolumeAttachment %v", attachID)) attach, err := c.k8s.StorageV1beta1().VolumeAttachments().Get(attachID, meta.GetOptions{}) if err != nil { + attached[spec] = false glog.Error(log("attacher.VolumesAreAttached failed for attach.ID=%v: %v", attachID, err)) continue } @@ -325,19 +356,7 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo // Start MountDevice nodeName := string(c.plugin.host.GetNodeName()) - attachID := getAttachmentName(csiSource.VolumeHandle, csiSource.Driver, nodeName) - - // search for attachment by VolumeAttachment.Spec.Source.PersistentVolumeName - attachment, err := c.k8s.StorageV1beta1().VolumeAttachments().Get(attachID, meta.GetOptions{}) - if err != nil { - return err // This err already has enough context ("VolumeAttachment xyz not found") - } - - if attachment == nil { - err = errors.New("no existing VolumeAttachment found") - return err - } - publishVolumeInfo := attachment.Status.AttachmentMetadata + publishVolumeInfo, err := c.plugin.getPublishVolumeInfo(c.k8s, csiSource.VolumeHandle, csiSource.Driver, nodeName) nodeStageSecrets := map[string]string{} if csiSource.NodeStageSecretRef != nil { diff --git a/pkg/volume/csi/csi_mounter.go b/pkg/volume/csi/csi_mounter.go index 57700895d26..4d57e4f6fa3 100644 --- a/pkg/volume/csi/csi_mounter.go +++ b/pkg/volume/csi/csi_mounter.go @@ -18,7 +18,6 @@ package csi import ( "context" - "errors" "fmt" "os" "path" @@ -26,7 +25,6 @@ import ( "github.com/golang/glog" api "k8s.io/api/core/v1" - meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" kstrings "k8s.io/kubernetes/pkg/util/strings" @@ -113,9 +111,6 @@ func (c *csiMountMgr) SetUpAt(dir string, fsGroup *int64) error { } csi := c.csiClient - nodeName := string(c.plugin.host.GetNodeName()) - attachID := getAttachmentName(csiSource.VolumeHandle, csiSource.Driver, nodeName) - ctx, cancel := context.WithTimeout(context.Background(), csiTimeout) defer cancel() @@ -134,20 +129,13 @@ func (c *csiMountMgr) SetUpAt(dir string, fsGroup *int64) error { return err } } - // search for attachment by VolumeAttachment.Spec.Source.PersistentVolumeName if c.volumeInfo == nil { - attachment, err := c.k8s.StorageV1beta1().VolumeAttachments().Get(attachID, meta.GetOptions{}) + nodeName := string(c.plugin.host.GetNodeName()) + c.volumeInfo, err = c.plugin.getPublishVolumeInfo(c.k8s, c.volumeID, c.driverName, nodeName) if err != nil { - glog.Error(log("mounter.SetupAt failed while getting volume attachment [id=%v]: %v", attachID, err)) return err } - - if attachment == nil { - glog.Error(log("unable to find VolumeAttachment [id=%s]", attachID)) - return errors.New("no existing VolumeAttachment found") - } - c.volumeInfo = attachment.Status.AttachmentMetadata } attribs := csiSource.VolumeAttributes diff --git a/pkg/volume/csi/csi_plugin.go b/pkg/volume/csi/csi_plugin.go index 04347924edd..e97864268eb 100644 --- a/pkg/volume/csi/csi_plugin.go +++ b/pkg/volume/csi/csi_plugin.go @@ -29,10 +29,12 @@ import ( "github.com/golang/glog" api "k8s.io/api/core/v1" + apierrs "k8s.io/apimachinery/pkg/api/errors" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" utilfeature "k8s.io/apiserver/pkg/util/feature" + clientset "k8s.io/client-go/kubernetes" csiapiinformer "k8s.io/csi-api/pkg/client/informers/externalversions" csiinformer "k8s.io/csi-api/pkg/client/informers/externalversions/csi/v1alpha1" csilister "k8s.io/csi-api/pkg/client/listers/csi/v1alpha1" @@ -490,3 +492,48 @@ func (p *csiPlugin) ConstructBlockVolumeSpec(podUID types.UID, specVolName, mapP return volume.NewSpecFromPersistentVolume(pv, false), nil } + +func (p *csiPlugin) skipAttach(driver string) (bool, error) { + if !utilfeature.DefaultFeatureGate.Enabled(features.CSISkipAttach) { + return false, nil + } + if p.csiDriverLister == nil { + return false, errors.New("CSIDriver lister does not exist") + } + csiDriver, err := p.csiDriverLister.Get(driver) + if err != nil { + if apierrs.IsNotFound(err) { + // Don't skip attach if CSIDriver does not exist + return false, nil + } + return false, err + } + if csiDriver.Spec.AttachRequired != nil && *csiDriver.Spec.AttachRequired == false { + return true, nil + } + return false, nil +} + +func (p *csiPlugin) getPublishVolumeInfo(client clientset.Interface, handle, driver, nodeName string) (map[string]string, error) { + skip, err := p.skipAttach(driver) + if err != nil { + return nil, err + } + if skip { + return nil, nil + } + + attachID := getAttachmentName(handle, driver, nodeName) + + // search for attachment by VolumeAttachment.Spec.Source.PersistentVolumeName + attachment, err := client.StorageV1beta1().VolumeAttachments().Get(attachID, meta.GetOptions{}) + if err != nil { + return nil, err // This err already has enough context ("VolumeAttachment xyz not found") + } + + if attachment == nil { + err = errors.New("no existing VolumeAttachment found") + return nil, err + } + return attachment.Status.AttachmentMetadata, nil +}