Skip to content

Commit

Permalink
[csi] Fix wait for status update and fix naming in LVMLogicalVolume (#9)
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksandr Zimin <alexandr.zimin@flant.com>
  • Loading branch information
AleksZimin committed Feb 27, 2024
1 parent 86f9a94 commit bbbf319
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 158 deletions.
14 changes: 7 additions & 7 deletions images/sds-lvm-csi/api/v1alpha1/lvm_logical_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type LvmLogicalVolumeList struct {
type LVMLogicalVolumeList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`

Items []LvmLogicalVolume `json:"items"`
Items []LVMLogicalVolume `json:"items"`
}

type LvmLogicalVolume struct {
type LVMLogicalVolume struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec LvmLogicalVolumeSpec `json:"spec"`
Status *LvmLogicalVolumeStatus `json:"status,omitempty"`
Spec LVMLogicalVolumeSpec `json:"spec"`
Status *LVMLogicalVolumeStatus `json:"status,omitempty"`
}

type LvmLogicalVolumeSpec struct {
type LVMLogicalVolumeSpec struct {
Type string `json:"type"`
Size resource.Quantity `json:"size"`
LvmVolumeGroup string `json:"lvmVolumeGroup"`
Expand All @@ -47,7 +47,7 @@ type ThinLogicalVolumeSpec struct {
PoolName string `json:"poolName"`
}

type LvmLogicalVolumeStatus struct {
type LVMLogicalVolumeStatus struct {
Phase string `json:"phase"`
Reason string `json:"reason"`
ActualSize resource.Quantity `json:"actualSize"`
Expand Down
6 changes: 3 additions & 3 deletions images/sds-lvm-csi/api/v1alpha1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (

const (
LVMVolumeGroupKind = "LvmVolumeGroup"
LVMLogicalVolumeKind = "LvmLogicalVolume"
LVMLogicalVolumeKind = "LVMLogicalVolume"
APIGroup = "storage.deckhouse.io"
APIVersion = "v1alpha1"
TypeMediaAPIVersion = APIGroup + "/" + APIVersion
Expand All @@ -45,8 +45,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&LvmVolumeGroup{},
&LvmVolumeGroupList{},
&LvmLogicalVolume{},
&LvmLogicalVolumeList{},
&LVMLogicalVolume{},
&LVMLogicalVolumeList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
Expand Down
20 changes: 10 additions & 10 deletions images/sds-lvm-csi/api/v1alpha1/zz_generated.deepcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,60 +76,60 @@ func (in *LvmVolumeGroupList) DeepCopyObject() runtime.Object {
return nil
}

// -------------- LvmLogicalVolume ----------
// -------------- LVMLogicalVolume ----------

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *LvmLogicalVolume) DeepCopyInto(out *LvmLogicalVolume) {
func (in *LVMLogicalVolume) DeepCopyInto(out *LVMLogicalVolume) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)

}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmptyBlockDevice.
func (in *LvmLogicalVolume) DeepCopy() *LvmLogicalVolume {
func (in *LVMLogicalVolume) DeepCopy() *LVMLogicalVolume {
if in == nil {
return nil
}
out := new(LvmLogicalVolume)
out := new(LVMLogicalVolume)
in.DeepCopyInto(out)
return out
}

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *LvmLogicalVolume) DeepCopyObject() runtime.Object {
func (in *LVMLogicalVolume) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *LvmLogicalVolumeList) DeepCopyInto(out *LvmLogicalVolumeList) {
func (in *LVMLogicalVolumeList) DeepCopyInto(out *LVMLogicalVolumeList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]LvmLogicalVolume, len(*in))
*out = make([]LVMLogicalVolume, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GuestbookList.
func (in *LvmLogicalVolumeList) DeepCopy() *LvmLogicalVolumeList {
func (in *LVMLogicalVolumeList) DeepCopy() *LVMLogicalVolumeList {
if in == nil {
return nil
}
out := new(LvmLogicalVolumeList)
out := new(LVMLogicalVolumeList)
in.DeepCopyInto(out)
return out
}

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *LvmLogicalVolumeList) DeepCopyObject() runtime.Object {
func (in *LVMLogicalVolumeList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
Expand Down
93 changes: 37 additions & 56 deletions images/sds-lvm-csi/driver/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ import (
"context"
"errors"
"fmt"
"sds-lvm-csi/api/v1alpha1"
"sds-lvm-csi/internal"
"sds-lvm-csi/pkg/utils"

kerrors "k8s.io/apimachinery/pkg/api/errors"

"github.com/container-storage-interface/spec/lib/go/csi"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"gopkg.in/yaml.v3"
"k8s.io/apimachinery/pkg/api/resource"
)

Expand All @@ -46,31 +45,24 @@ func (d *Driver) CreateVolume(ctx context.Context, request *csi.CreateVolumeRequ
return nil, status.Error(codes.InvalidArgument, "Volume Capability cannot de empty")
}

LvmBindingMode := request.GetParameters()[lvmBindingMode]
LvmBindingMode := request.GetParameters()[internal.LvmBindingModeKey]
d.log.Info(fmt.Sprintf("storage class LvmBindingMode: %s", LvmBindingMode))

LvmType := request.GetParameters()[lvmType]
LvmType := request.GetParameters()[internal.LvmTypeKey]
d.log.Info(fmt.Sprintf("storage class LvmType: %s", LvmType))

if len(request.GetParameters()[lvmVolumeGroup]) == 0 {
if len(request.GetParameters()[internal.LvmVolumeGroupKey]) == 0 {
err := errors.New("no LVMVolumeGroups specified in a storage class's parameters")
d.log.Error(err, fmt.Sprintf("no LVMVolumeGroups were found for the request: %+v", request))
return nil, status.Errorf(codes.InvalidArgument, err.Error())
}

var lvmVolumeGroups LVMVolumeGroups
err := yaml.Unmarshal([]byte(request.GetParameters()[lvmVolumeGroup]), &lvmVolumeGroups)
storageClassLVGs, storageClassLVGParametersMap, err := utils.GetStorageClassLVGsAndParameters(ctx, d.cl, *d.log, request.GetParameters()[internal.LvmVolumeGroupKey])
if err != nil {
d.log.Error(err, "unmarshal yaml lvmVolumeGroup")
}

lvmVG := make(map[string]string, len(lvmVolumeGroups))
for _, v := range lvmVolumeGroups {
lvmVG[v.Name] = v.Thin.PoolName
d.log.Error(err, "error GetStorageClassLVGs")
return nil, status.Errorf(codes.Internal, err.Error())
}

d.log.Info(fmt.Sprintf("StorageClass LVM volume groups names: %+v", lvmVG))

llvName := request.Name
d.log.Info(fmt.Sprintf("llv name: %s ", llvName))

Expand All @@ -79,52 +71,39 @@ func (d *Driver) CreateVolume(ctx context.Context, request *csi.CreateVolumeRequ

var preferredNode string
switch LvmBindingMode {
case BindingModeI:
d.log.Info(fmt.Sprintf("LvmBindingMode is %s. Start selecting node", BindingModeI))
selectedNodeName, freeSpace, err := utils.GetNodeMaxFreeVGSize(ctx, d.cl)
case internal.BindingModeI:
d.log.Info(fmt.Sprintf("LvmBindingMode is %s. Start selecting node", internal.BindingModeI))
selectedNodeName, freeSpace, err := utils.GetNodeWithMaxFreeSpace(*d.log, storageClassLVGs, storageClassLVGParametersMap, LvmType)
if err != nil {
d.log.Error(err, "error GetNodeMaxVGSize")
}

preferredNode = selectedNodeName
if llvSize.Value() > freeSpace.Value() {
return nil, status.Errorf(codes.Internal, "requested size: %s is greater than free space: %s", llvSize.String(), freeSpace.String())
}
d.log.Info(fmt.Sprintf("Selected node: %s, free space %s ", selectedNodeName, freeSpace.String()))
case BindingModeWFFC:
d.log.Info(fmt.Sprintf("LvmBindingMode is %s. Get preferredNode", BindingModeWFFC))
if LvmType == internal.LLMTypeThick {
if llvSize.Value() > freeSpace.Value() {
return nil, status.Errorf(codes.Internal, "requested size: %s is greater than free space: %s", llvSize.String(), freeSpace.String())
}
}
case internal.BindingModeWFFC:
d.log.Info(fmt.Sprintf("LvmBindingMode is %s. Get preferredNode", internal.BindingModeWFFC))
if len(request.AccessibilityRequirements.Preferred) != 0 {
t := request.AccessibilityRequirements.Preferred[0].Segments
preferredNode = t[topologyKey]
preferredNode = t[internal.TopologyKey]
}
}

lvmVolumeGroupName, vgName, err := utils.GetLVMVolumeGroupParams(ctx, d.cl, *d.log, lvmVG, preferredNode, LvmType)
selectedLVG, err := utils.SelectLVG(storageClassLVGs, storageClassLVGParametersMap, preferredNode)
if err != nil {
d.log.Error(err, "error GetVGName")
d.log.Error(err, "error SelectLVG")
return nil, status.Errorf(codes.Internal, err.Error())
}

d.log.Info(fmt.Sprintf("LvmVolumeGroup: %s", lvmVolumeGroupName))
d.log.Info(fmt.Sprintf("VGName: %s", vgName))
d.log.Info(fmt.Sprintf("prefered node: %s", preferredNode))
llvSpec := utils.GetLLVSpec(*d.log, selectedLVG, storageClassLVGParametersMap, preferredNode, LvmType, *llvSize)
d.log.Info(fmt.Sprintf("LVMLogicalVolumeSpec : %+v", llvSpec))

d.log.Info("------------ CreateLVMLogicalVolume ------------")
var llvThin *v1alpha1.ThinLogicalVolumeSpec
if LvmType == LLVTypeThin {
llvThin = &v1alpha1.ThinLogicalVolumeSpec{}
llvThin.PoolName = lvmVG[lvmVolumeGroupName]
}

spec := v1alpha1.LvmLogicalVolumeSpec{
Type: LvmType,
Size: *llvSize,
LvmVolumeGroup: lvmVolumeGroupName,
Thin: llvThin,
}

d.log.Info(fmt.Sprintf("LvmLogicalVolumeSpec : %+v", spec))

_, err = utils.CreateLVMLogicalVolume(ctx, d.cl, llvName, spec)
_, err = utils.CreateLVMLogicalVolume(ctx, d.cl, llvName, llvSpec)
if err != nil {
if kerrors.IsAlreadyExists(err) {
d.log.Info(fmt.Sprintf("LVMLogicalVolume %s already exists", llvName))
Expand All @@ -136,7 +115,7 @@ func (d *Driver) CreateVolume(ctx context.Context, request *csi.CreateVolumeRequ
d.log.Info("------------ CreateLVMLogicalVolume ------------")

d.log.Info("start wait CreateLVMLogicalVolume ")
resizeDelta, err := resource.ParseQuantity(ResizeDelta)
resizeDelta, err := resource.ParseQuantity(internal.ResizeDelta)
if err != nil {
d.log.Error(err, "error ParseQuantity for ResizeDelta")
return nil, err
Expand All @@ -153,8 +132,8 @@ func (d *Driver) CreateVolume(ctx context.Context, request *csi.CreateVolumeRequ
volumeCtx[k] = v
}

volumeCtx[subPath] = request.Name
volumeCtx[VGNameKey] = vgName
volumeCtx[internal.SubPath] = request.Name
volumeCtx[internal.VGNameKey] = selectedLVG.Spec.ActualVGNameOnTheNode

return &csi.CreateVolumeResponse{
Volume: &csi.Volume{
Expand All @@ -164,7 +143,7 @@ func (d *Driver) CreateVolume(ctx context.Context, request *csi.CreateVolumeRequ
ContentSource: request.VolumeContentSource,
AccessibleTopology: []*csi.Topology{
{Segments: map[string]string{
topologyKey: preferredNode,
internal.TopologyKey: preferredNode,
}},
},
},
Expand Down Expand Up @@ -278,7 +257,7 @@ func (d *Driver) ControllerExpandVolume(ctx context.Context, request *csi.Contro
return nil, status.Errorf(codes.Internal, "error getting LVMLogicalVolume: %s", err.Error())
}

resizeDelta, err := resource.ParseQuantity(ResizeDelta)
resizeDelta, err := resource.ParseQuantity(internal.ResizeDelta)
if err != nil {
d.log.Error(err, "error ParseQuantity for ResizeDelta")
return nil, err
Expand Down Expand Up @@ -306,13 +285,15 @@ func (d *Driver) ControllerExpandVolume(ctx context.Context, request *csi.Contro
return nil, status.Errorf(codes.Internal, "error getting LVMVolumeGroup: %v", err)
}

lvgFreeSpace, err := utils.GetLVMVolumeGroupFreeSpace(*lvg)
if err != nil {
return nil, status.Errorf(codes.Internal, "error getting LVMVolumeGroupCapacity: %v", err)
}
if llv.Spec.Type == internal.LLMTypeThick {
lvgFreeSpace, err := utils.GetLVMVolumeGroupFreeSpace(*lvg)
if err != nil {
return nil, status.Errorf(codes.Internal, "error getting LVMVolumeGroupCapacity: %v", err)
}

if lvgFreeSpace.Value() < (requestCapacity.Value() - llv.Status.ActualSize.Value()) {
return nil, status.Errorf(codes.Internal, "requested size: %s is greater than the capacity of the LVMVolumeGroup: %s", requestCapacity.String(), lvgFreeSpace.String())
if lvgFreeSpace.Value() < (requestCapacity.Value() - llv.Status.ActualSize.Value()) {
return nil, status.Errorf(codes.Internal, "requested size: %s is greater than the capacity of the LVMVolumeGroup: %s", requestCapacity.String(), lvgFreeSpace.String())
}
}

d.log.Info("start resize LVMLogicalVolume")
Expand Down
5 changes: 3 additions & 2 deletions images/sds-lvm-csi/driver/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package driver
import (
"context"
"fmt"
"sds-lvm-csi/internal"

"github.com/container-storage-interface/spec/lib/go/csi"
"google.golang.org/grpc/codes"
Expand All @@ -41,7 +42,7 @@ func (d *Driver) NodePublishVolume(ctx context.Context, request *csi.NodePublish
d.log.Info(request.String())
d.log.Info("------------- NodePublishVolume --------------")

dev := fmt.Sprintf("/dev/%s/%s", request.GetVolumeContext()[VGNameKey], request.VolumeId)
dev := fmt.Sprintf("/dev/%s/%s", request.GetVolumeContext()[internal.VGNameKey], request.VolumeId)

var mountOptions []string
if request.GetReadonly() {
Expand Down Expand Up @@ -145,7 +146,7 @@ func (d *Driver) NodeGetInfo(ctx context.Context, request *csi.NodeGetInfoReques
MaxVolumesPerNode: 10,
AccessibleTopology: &csi.Topology{
Segments: map[string]string{
topologyKey: d.hostID,
internal.TopologyKey: d.hostID,
},
},
}, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package driver
package internal

const (
lvmType = "lvm.csi.storage.deckhouse.io/lvm-type"
lvmBindingMode = "lvm.csi.storage.deckhouse.io/volume-binding-mode"
lvmVolumeGroup = "lvm.csi.storage.deckhouse.io/lvm-volume-groups"
topologyKey = "topology.sds-lvm-csi/node"
subPath = "subPath"
VGNameKey = "vgname"
LLVTypeThin = "Thin"
LLVTypeThick = "Thick"
LLVStatusCreated = "Created"
BindingModeWFFC = "WaitForFirstConsumer"
BindingModeI = "Immediate"
ResizeDelta = "32Mi"
LvmTypeKey = "lvm.csi.storage.deckhouse.io/lvm-type"
LvmBindingModeKey = "lvm.csi.storage.deckhouse.io/volume-binding-mode"
LvmVolumeGroupKey = "lvm.csi.storage.deckhouse.io/lvm-volume-groups"
TopologyKey = "topology.sds-lvm-csi/node"
SubPath = "subPath"
VGNameKey = "vgname"
LLMTypeThin = "Thin"
LLMTypeThick = "Thick"
LLVStatusCreated = "Created"
BindingModeWFFC = "WaitForFirstConsumer"
BindingModeI = "Immediate"
ResizeDelta = "32Mi"
)
Loading

0 comments on commit bbbf319

Please sign in to comment.