Skip to content

Commit

Permalink
[cinder-csi-plugin] ephemeral volume removal (kubernetes#2602)
Browse files Browse the repository at this point in the history
Disable creating new deprecated ephemeral volumes

Signed-off-by: Serge Logvinov <[email protected]>
  • Loading branch information
sergelogvinov authored Aug 6, 2024
1 parent 515b4c9 commit 75b1fbb
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 146 deletions.
124 changes: 3 additions & 121 deletions pkg/csi/cinder/nodeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"

"github.com/container-storage-interface/spec/lib/go/csi"
Expand Down Expand Up @@ -68,22 +67,14 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis

ephemeralVolume := req.GetVolumeContext()["csi.storage.k8s.io/ephemeral"] == "true"
if ephemeralVolume {
// See https://github.com/kubernetes/cloud-provider-openstack/issues/1493
klog.Warningf("CSI inline ephemeral volumes support is deprecated in 1.24 release.")
return nodePublishEphemeral(req, ns)
// See https://github.com/kubernetes/cloud-provider-openstack/issues/2599
return nil, status.Error(codes.Unimplemented, "CSI inline ephemeral volumes support is removed in 1.31 release.")
}

// In case of ephemeral volume staging path not provided
if len(source) == 0 {
return nil, status.Error(codes.InvalidArgument, "NodePublishVolume Staging Target Path must be provided")
}
_, err := ns.Cloud.GetVolume(volumeID)
if err != nil {
if cpoerrors.IsNotFound(err) {
return nil, status.Error(codes.NotFound, "Volume not found")
}
return nil, status.Errorf(codes.Internal, "GetVolume failed with error %v", err)
}

mountOptions := []string{"bind"}
if req.GetReadonly() {
Expand Down Expand Up @@ -121,105 +112,6 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis
return &csi.NodePublishVolumeResponse{}, nil
}

func nodePublishEphemeral(req *csi.NodePublishVolumeRequest, ns *nodeServer) (*csi.NodePublishVolumeResponse, error) {

var size int
var err error

volID := req.GetVolumeId()
volName := fmt.Sprintf("ephemeral-%s", volID)
properties := map[string]string{"cinder.csi.openstack.org/cluster": ns.Driver.cluster}
capacity, ok := req.GetVolumeContext()["capacity"]

volAvailability, err := ns.Metadata.GetAvailabilityZone()
if err != nil {
return nil, status.Errorf(codes.Internal, "retrieving availability zone from MetaData service failed with error %v", err)
}

size = 1 // default size is 1GB
if ok && strings.HasSuffix(capacity, "Gi") {
size, err = strconv.Atoi(strings.TrimSuffix(capacity, "Gi"))
if err != nil {
klog.V(3).Infof("Unable to parse capacity: %v", err)
return nil, status.Errorf(codes.Internal, "Unable to parse capacity %v", err)
}
}

// Check type in given param, if not, use ""
volumeType, ok := req.GetVolumeContext()["type"]
if !ok {
volumeType = ""
}

evol, err := ns.Cloud.CreateVolume(volName, size, volumeType, volAvailability, "", "", "", properties)

if err != nil {
klog.V(3).Infof("Failed to Create Ephemeral Volume: %v", err)
return nil, status.Errorf(codes.Internal, "Failed to create Ephemeral Volume %v", err)
}

// Wait for volume status to be Available, before attaching
if evol.Status != openstack.VolumeAvailableStatus {
targetStatus := []string{openstack.VolumeAvailableStatus}
err := ns.Cloud.WaitVolumeTargetStatus(evol.ID, targetStatus)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
}

klog.V(4).Infof("Ephemeral Volume %s is created", evol.ID)

// attach volume
// for attach volume we need to have information about node.
nodeID, err := ns.Metadata.GetInstanceID()
if err != nil {
msg := "nodePublishEphemeral: Failed to get Instance ID: %v"
klog.V(3).Infof(msg, err)
return nil, status.Errorf(codes.Internal, msg, err)
}

_, err = ns.Cloud.AttachVolume(nodeID, evol.ID)
if err != nil {
msg := "nodePublishEphemeral: attach volume %s failed with error: %v"
klog.V(3).Infof(msg, evol.ID, err)
return nil, status.Errorf(codes.Internal, msg, evol.ID, err)
}

err = ns.Cloud.WaitDiskAttached(nodeID, evol.ID)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

m := ns.Mount

devicePath, err := getDevicePath(evol.ID, m)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unable to find Device path for volume: %v", err)
}

targetPath := req.GetTargetPath()

// Verify whether mounted
notMnt, err := m.IsLikelyNotMountPointAttach(targetPath)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

// Volume Mount
if notMnt {
// set default fstype is ext4
fsType := "ext4"
// Mount
err = m.Mounter().FormatAndMount(devicePath, targetPath, fsType, nil)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
}

return &csi.NodePublishVolumeResponse{}, nil

}

func nodePublishVolumeForBlock(req *csi.NodePublishVolumeRequest, ns *nodeServer, mountOptions []string) (*csi.NodePublishVolumeResponse, error) {
klog.V(4).Infof("NodePublishVolumeBlock: called with args %+v", protosanitizer.StripSecrets(*req))

Expand Down Expand Up @@ -274,7 +166,6 @@ func (ns *nodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu
ephemeralVolume := false

vol, err := ns.Cloud.GetVolume(volumeID)

if err != nil {

if !cpoerrors.IsNotFound(err) {
Expand Down Expand Up @@ -459,16 +350,7 @@ func (ns *nodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
return nil, status.Error(codes.InvalidArgument, "NodeUnstageVolume Staging Target Path must be provided")
}

_, err := ns.Cloud.GetVolume(volumeID)
if err != nil {
if cpoerrors.IsNotFound(err) {
klog.V(4).Infof("NodeUnstageVolume: Unable to find volume: %v", err)
return nil, status.Error(codes.NotFound, "Volume not found")
}
return nil, status.Errorf(codes.Internal, "GetVolume failed with error %v", err)
}

err = ns.Mount.UnmountPath(stagingTargetPath)
err := ns.Mount.UnmountPath(stagingTargetPath)
if err != nil {
return nil, status.Errorf(codes.Internal, "Unmount of targetPath %s failed with error %v", stagingTargetPath, err)
}
Expand Down
29 changes: 4 additions & 25 deletions pkg/csi/cinder/nodeserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (

"github.com/container-storage-interface/spec/lib/go/csi"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"k8s.io/cloud-provider-openstack/pkg/csi/cinder/openstack"
"k8s.io/cloud-provider-openstack/pkg/util/metadata"
"k8s.io/cloud-provider-openstack/pkg/util/mount"
Expand Down Expand Up @@ -129,31 +131,13 @@ func TestNodePublishVolumeEphermeral(t *testing.T) {

properties := map[string]string{"cinder.csi.openstack.org/cluster": FakeCluster}
fvolName := fmt.Sprintf("ephemeral-%s", FakeVolID)
tState := []string{"available"}

omock.On("CreateVolume", fvolName, 2, "test", "nova", "", "", "", properties).Return(&FakeVol, nil)

omock.On("AttachVolume", FakeNodeID, FakeVolID).Return(FakeVolID, nil)
omock.On("WaitDiskAttached", FakeNodeID, FakeVolID).Return(nil)
omock.On("WaitVolumeTargetStatus", FakeVolID, tState).Return(nil)
mmock.On("GetDevicePath", FakeVolID).Return(FakeDevicePath, nil)
mmock.On("IsLikelyNotMountPointAttach", FakeTargetPath).Return(true, nil)
metamock.On("GetAvailabilityZone").Return(FakeAvailability, nil)

mount.MInstance = mmock
metadata.MetadataService = metamock
openstack.OsInstances = map[string]openstack.IOpenStack{
"": omock,
}

d := NewDriver(&DriverOpts{Endpoint: FakeEndpoint, ClusterID: FakeCluster})
fakeNse := NewNodeServer(d, mount.MInstance, metadata.MetadataService, openstack.OsInstances[""], map[string]string{})

// Init assert
assert := assert.New(t)

// Expected Result
expectedRes := &csi.NodePublishVolumeResponse{}
stdVolCap := &csi.VolumeCapability{
AccessType: &csi.VolumeCapability_Mount{
Mount: &csi.VolumeCapability_MountVolume{},
Expand All @@ -174,13 +158,8 @@ func TestNodePublishVolumeEphermeral(t *testing.T) {
}

// Invoke NodePublishVolume
actualRes, err := fakeNse.NodePublishVolume(FakeCtx, fakeReq)
if err != nil {
t.Errorf("failed to NodePublishVolume: %v", err)
}

// Assert
assert.Equal(expectedRes, actualRes)
_, err := fakeNs.NodePublishVolume(FakeCtx, fakeReq)
assert.Equal(status.Error(codes.Unimplemented, "CSI inline ephemeral volumes support is removed in 1.31 release."), err)
}

// Test NodeStageVolume
Expand Down

0 comments on commit 75b1fbb

Please sign in to comment.