diff --git a/crds/lvmstorageclass.yaml b/crds/lvmstorageclass.yaml index 2e77c6aa..c4e45cfb 100644 --- a/crds/lvmstorageclass.yaml +++ b/crds/lvmstorageclass.yaml @@ -11,7 +11,7 @@ spec: names: plural: lvmstorageclasses singular: lvmstorageclass - kind: LvmStorageClass + kind: LVMStorageClass shortNames: - lsc preserveUnknownFields: false @@ -35,7 +35,6 @@ spec: - type - reclaimPolicy - volumeBindingMode - - allowVolumeExpansion - lvmVolumeGroups properties: isDefault: @@ -79,10 +78,6 @@ spec: enum: - Immediate - WaitForFirstConsumer - allowVolumeExpansion: - type: boolean - description: | - Configure if Persistent Volume is going to be expandable. lvmVolumeGroups: type: array x-kubernetes-validations: diff --git a/images/sds-lvm-controller/api/v1alpha1/lvm_storage_class.go b/images/sds-lvm-controller/api/v1alpha1/lvm_storage_class.go index 5e272ead..7db19641 100644 --- a/images/sds-lvm-controller/api/v1alpha1/lvm_storage_class.go +++ b/images/sds-lvm-controller/api/v1alpha1/lvm_storage_class.go @@ -18,39 +18,38 @@ package v1alpha1 import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -type LvmStorageClass struct { +type LVMStorageClass struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec LvmStorageClassSpec `json:"spec"` - Status *LvmStorageClassStatus `json:"status,omitempty"` + Spec LVMStorageClassSpec `json:"spec"` + Status *LVMStorageClassStatus `json:"status,omitempty"` } -// LvmStorageClassList contains a list of empty block device -type LvmStorageClassList struct { +// LVMStorageClassList contains a list of empty block device +type LVMStorageClassList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata"` - Items []LvmStorageClass `json:"items"` + Items []LVMStorageClass `json:"items"` } -type LvmStorageClassSpec struct { - IsDefault bool `json:"isDefault"` - Type string `json:"type"` - ReclaimPolicy string `json:"reclaimPolicy"` - VolumeBindingMode string `json:"volumeBindingMode"` - AllowVolumeExpansion bool `json:"allowVolumeExpansion"` - LVMVolumeGroups []LvmStorageClassLVG `json:"lvmVolumeGroups"` +type LVMStorageClassSpec struct { + IsDefault bool `json:"isDefault"` + Type string `json:"type"` + ReclaimPolicy string `json:"reclaimPolicy"` + VolumeBindingMode string `json:"volumeBindingMode"` + LVMVolumeGroups []LVMStorageClassLVG `json:"lvmVolumeGroups"` } -type LvmStorageClassStatus struct { +type LVMStorageClassStatus struct { Phase string `json:"phase,omitempty"` Reason string `json:"reason,omitempty"` } -type LvmStorageClassLVG struct { +type LVMStorageClassLVG struct { Name string `json:"name"` - Thin *LvmStorageClassThinPool `json:"thin,omitempty"` + Thin *LVMStorageClassThinPool `json:"thin,omitempty"` } -type LvmStorageClassThinPool struct { +type LVMStorageClassThinPool struct { PoolName string `json:"poolName"` } diff --git a/images/sds-lvm-controller/api/v1alpha1/register.go b/images/sds-lvm-controller/api/v1alpha1/register.go index f5f0c2d2..9a4263a1 100644 --- a/images/sds-lvm-controller/api/v1alpha1/register.go +++ b/images/sds-lvm-controller/api/v1alpha1/register.go @@ -23,7 +23,7 @@ import ( ) const ( - LvmStorageClassKind = "LvmStorageClass" + LVMStorageClassKind = "LVMStorageClass" APIGroup = "storage.deckhouse.io" APIVersion = "v1alpha1" ) @@ -41,8 +41,8 @@ var ( // Adds the list of known types to Scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &LvmStorageClass{}, - &LvmStorageClassList{}, + &LVMStorageClass{}, + &LVMStorageClassList{}, &LvmVolumeGroup{}, &LvmVolumeGroupList{}, ) diff --git a/images/sds-lvm-controller/api/v1alpha1/zz_generated.deepcopy.go b/images/sds-lvm-controller/api/v1alpha1/zz_generated.deepcopy.go index 4cb1ee90..8a0e05f3 100644 --- a/images/sds-lvm-controller/api/v1alpha1/zz_generated.deepcopy.go +++ b/images/sds-lvm-controller/api/v1alpha1/zz_generated.deepcopy.go @@ -19,7 +19,7 @@ package v1alpha1 import "k8s.io/apimachinery/pkg/runtime" // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LvmStorageClass) DeepCopyInto(out *LvmStorageClass) { +func (in *LVMStorageClass) DeepCopyInto(out *LVMStorageClass) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -27,17 +27,17 @@ func (in *LvmStorageClass) DeepCopyInto(out *LvmStorageClass) { } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmptyBlockDevice. -func (in *LvmStorageClass) DeepCopy() *LvmStorageClass { +func (in *LVMStorageClass) DeepCopy() *LVMStorageClass { if in == nil { return nil } - out := new(LvmStorageClass) + out := new(LVMStorageClass) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *LvmStorageClass) DeepCopyObject() runtime.Object { +func (in *LVMStorageClass) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -45,13 +45,13 @@ func (in *LvmStorageClass) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LvmStorageClassList) DeepCopyInto(out *LvmStorageClassList) { +func (in *LVMStorageClassList) DeepCopyInto(out *LVMStorageClassList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]LvmStorageClass, len(*in)) + *out = make([]LVMStorageClass, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -59,17 +59,17 @@ func (in *LvmStorageClassList) DeepCopyInto(out *LvmStorageClassList) { } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GuestbookList. -func (in *LvmStorageClassList) DeepCopy() *LvmStorageClassList { +func (in *LVMStorageClassList) DeepCopy() *LVMStorageClassList { if in == nil { return nil } - out := new(LvmStorageClassList) + out := new(LVMStorageClassList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *LvmStorageClassList) DeepCopyObject() runtime.Object { +func (in *LVMStorageClassList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } diff --git a/images/sds-lvm-controller/pkg/controller/lvm_storage_class_watcher.go b/images/sds-lvm-controller/pkg/controller/lvm_storage_class_watcher.go index 1ba040ff..8d8d6449 100644 --- a/images/sds-lvm-controller/pkg/controller/lvm_storage_class_watcher.go +++ b/images/sds-lvm-controller/pkg/controller/lvm_storage_class_watcher.go @@ -62,6 +62,8 @@ const ( DefaultStorageClassAnnotationKey = "storageclass.kubernetes.io/is-default-class" LVMStorageClassFinalizerName = "lvmstorageclass.storage.deckhouse.io" + AllowVolumeExpansionDefaultValue = true + FailedStatusPhase = "Failed" CreatedStatusPhase = "Created" @@ -85,7 +87,7 @@ func RunLVMStorageClassWatcherController( c, err := controller.New(LVMStorageClassCtrlName, mgr, controller.Options{ Reconciler: reconcile.Func(func(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { log.Info("[LVMStorageClassReconciler] starts Reconcile") - lsc := &v1alpha1.LvmStorageClass{} + lsc := &v1alpha1.LVMStorageClass{} err := cl.Get(ctx, request.NamespacedName, lsc) if err != nil && !errors2.IsNotFound(err) { log.Error(err, fmt.Sprintf("[LVMStorageClassReconciler] unable to get LVMStorageClass, name: %s", request.Name)) @@ -120,10 +122,10 @@ func RunLVMStorageClassWatcherController( return nil, err } - err = c.Watch(source.Kind(mgr.GetCache(), &v1alpha1.LvmStorageClass{}), handler.Funcs{ + err = c.Watch(source.Kind(mgr.GetCache(), &v1alpha1.LVMStorageClass{}), handler.Funcs{ CreateFunc: func(ctx context.Context, e event.CreateEvent, q workqueue.RateLimitingInterface) { log.Info(fmt.Sprintf("[CreateFunc] starts the reconciliation for the LVMStorageClass %s", e.Object.GetName())) - lsc, ok := e.Object.(*v1alpha1.LvmStorageClass) + lsc, ok := e.Object.(*v1alpha1.LVMStorageClass) if !ok { err = errors.New("unable to cast event object to a given type") log.Error(err, "[CreateFunc] an error occurred while handling create event") @@ -162,7 +164,7 @@ func RunLVMStorageClassWatcherController( }, UpdateFunc: func(ctx context.Context, e event.UpdateEvent, q workqueue.RateLimitingInterface) { log.Info(fmt.Sprintf("[UpdateFunc] starts the reconciliation for the LVMStorageClass %s", e.ObjectNew.GetName())) - lsc, ok := e.ObjectNew.(*v1alpha1.LvmStorageClass) + lsc, ok := e.ObjectNew.(*v1alpha1.LVMStorageClass) if !ok { err = errors.New("unable to cast event object to a given type") log.Error(err, "[UpdateFunc] an error occurred while handling create event") @@ -209,7 +211,7 @@ func RunLVMStorageClassWatcherController( return c, nil } -func runEventReconcile(ctx context.Context, cl client.Client, log logger.Logger, scList *v1.StorageClassList, lsc *v1alpha1.LvmStorageClass) (bool, error) { +func runEventReconcile(ctx context.Context, cl client.Client, log logger.Logger, scList *v1.StorageClassList, lsc *v1alpha1.LVMStorageClass) (bool, error) { recType := identifyReconcileFunc(scList, lsc) log.Debug(fmt.Sprintf("[runEventReconcile] reconcile operation: %s", recType)) switch recType { @@ -234,7 +236,7 @@ func reconcileLSCDeleteFunc( cl client.Client, log logger.Logger, scList *v1.StorageClassList, - lsc *v1alpha1.LvmStorageClass, + lsc *v1alpha1.LVMStorageClass, ) (bool, error) { log.Debug(fmt.Sprintf("[reconcileLSCDeleteFunc] tries to find a storage class for the LVMStorageClass %s", lsc.Name)) var sc *v1.StorageClass @@ -286,7 +288,7 @@ func reconcileLSCDeleteFunc( return false, nil } -func removeLVMSCFinalizerIfExists(ctx context.Context, cl client.Client, lsc *v1alpha1.LvmStorageClass) (bool, error) { +func removeLVMSCFinalizerIfExists(ctx context.Context, cl client.Client, lsc *v1alpha1.LVMStorageClass) (bool, error) { removed := false for i, f := range lsc.Finalizers { if f == LVMStorageClassFinalizerName { @@ -311,7 +313,7 @@ func reconcileLSCUpdateFunc( cl client.Client, log logger.Logger, scList *v1.StorageClassList, - lsc *v1alpha1.LvmStorageClass, + lsc *v1alpha1.LVMStorageClass, ) (bool, error) { log.Debug(fmt.Sprintf("[reconcileLSCUpdateFunc] starts the LVMStorageClass %s validation", lsc.Name)) valid, msg := validateLVMStorageClass(ctx, cl, scList, lsc) @@ -365,7 +367,7 @@ func reconcileLSCUpdateFunc( return false, nil } -func patchSCByLSC(sc *v1.StorageClass, lsc *v1alpha1.LvmStorageClass) *v1.StorageClass { +func patchSCByLSC(sc *v1.StorageClass, lsc *v1alpha1.LVMStorageClass) *v1.StorageClass { lscDefault := "false" if lsc.Spec.IsDefault { lscDefault = "true" @@ -373,13 +375,10 @@ func patchSCByLSC(sc *v1.StorageClass, lsc *v1alpha1.LvmStorageClass) *v1.Storag sc.Annotations[DefaultStorageClassAnnotationKey] = lscDefault - // TODO: remove it - sc.AllowVolumeExpansion = &lsc.Spec.AllowVolumeExpansion - return sc } -func identifyReconcileFunc(scList *v1.StorageClassList, lsc *v1alpha1.LvmStorageClass) reconcileType { +func identifyReconcileFunc(scList *v1.StorageClassList, lsc *v1alpha1.LVMStorageClass) reconcileType { should := shouldReconcileByCreateFunc(scList, lsc) if should { return CreateReconcile @@ -398,7 +397,7 @@ func identifyReconcileFunc(scList *v1.StorageClassList, lsc *v1alpha1.LvmStorage return "none" } -func shouldReconcileByDeleteFunc(lsc *v1alpha1.LvmStorageClass) bool { +func shouldReconcileByDeleteFunc(lsc *v1alpha1.LVMStorageClass) bool { if lsc.DeletionTimestamp != nil { return true } @@ -406,7 +405,7 @@ func shouldReconcileByDeleteFunc(lsc *v1alpha1.LvmStorageClass) bool { return false } -func shouldReconcileByUpdateFunc(scList *v1.StorageClassList, lsc *v1alpha1.LvmStorageClass) bool { +func shouldReconcileByUpdateFunc(scList *v1.StorageClassList, lsc *v1alpha1.LVMStorageClass) bool { if lsc.DeletionTimestamp != nil { return false } @@ -425,18 +424,13 @@ func shouldReconcileByUpdateFunc(scList *v1.StorageClassList, lsc *v1alpha1.LvmS if sc.Annotations[DefaultStorageClassAnnotationKey] != lscDefault { return true } - - // TODO: remove it - if *sc.AllowVolumeExpansion != lsc.Spec.AllowVolumeExpansion { - return true - } } } return false } -func shouldReconcileByCreateFunc(scList *v1.StorageClassList, lsc *v1alpha1.LvmStorageClass) bool { +func shouldReconcileByCreateFunc(scList *v1.StorageClassList, lsc *v1alpha1.LVMStorageClass) bool { for _, sc := range scList.Items { if sc.Name == lsc.Name && lsc.Status != nil { @@ -452,7 +446,7 @@ func reconcileLSCCreateFunc( cl client.Client, log logger.Logger, scList *v1.StorageClassList, - lsc *v1alpha1.LvmStorageClass, + lsc *v1alpha1.LVMStorageClass, ) (bool, error) { log.Debug(fmt.Sprintf("[reconcileLSCCreateFunc] starts the LVMStorageClass %s validation", lsc.Name)) valid, msg := validateLVMStorageClass(ctx, cl, scList, lsc) @@ -534,7 +528,7 @@ func createStorageClassIfNotExists( return true, err } -func addFinalizerIfNotExists(ctx context.Context, cl client.Client, lsc *v1alpha1.LvmStorageClass) (bool, error) { +func addFinalizerIfNotExists(ctx context.Context, cl client.Client, lsc *v1alpha1.LVMStorageClass) (bool, error) { if !slices.Contains(lsc.Finalizers, LVMStorageClassFinalizerName) { lsc.Finalizers = append(lsc.Finalizers, LVMStorageClassFinalizerName) } @@ -547,9 +541,10 @@ func addFinalizerIfNotExists(ctx context.Context, cl client.Client, lsc *v1alpha return true, nil } -func configureStorageClass(lsc *v1alpha1.LvmStorageClass) (*v1.StorageClass, error) { +func configureStorageClass(lsc *v1alpha1.LVMStorageClass) (*v1.StorageClass, error) { reclaimPolicy := corev1.PersistentVolumeReclaimPolicy(lsc.Spec.ReclaimPolicy) volumeBindingMode := v1.VolumeBindingMode(lsc.Spec.VolumeBindingMode) + AllowVolumeExpansion := AllowVolumeExpansionDefaultValue lvgsParam, err := yaml.Marshal(lsc.Spec.LVMVolumeGroups) if err != nil { @@ -579,9 +574,8 @@ func configureStorageClass(lsc *v1alpha1.LvmStorageClass) (*v1.StorageClass, err LVMVolumeBindingModeParamKey: lsc.Spec.VolumeBindingMode, LVMVolumeGroupsParamKey: string(lvgsParam), }, - ReclaimPolicy: &reclaimPolicy, - // TODO: add constant - AllowVolumeExpansion: &lsc.Spec.AllowVolumeExpansion, + ReclaimPolicy: &reclaimPolicy, + AllowVolumeExpansion: &AllowVolumeExpansion, VolumeBindingMode: &volumeBindingMode, } @@ -591,12 +585,12 @@ func configureStorageClass(lsc *v1alpha1.LvmStorageClass) (*v1.StorageClass, err func updateLVMStorageClassPhase( ctx context.Context, cl client.Client, - lsc *v1alpha1.LvmStorageClass, + lsc *v1alpha1.LVMStorageClass, phase, reason string, ) error { if lsc.Status == nil { - lsc.Status = new(v1alpha1.LvmStorageClassStatus) + lsc.Status = new(v1alpha1.LVMStorageClassStatus) } lsc.Status.Phase = phase lsc.Status.Reason = reason @@ -614,7 +608,7 @@ func validateLVMStorageClass( ctx context.Context, cl client.Client, scList *v1.StorageClassList, - lsc *v1alpha1.LvmStorageClass, + lsc *v1alpha1.LVMStorageClass, ) (bool, string) { var ( failedMsgBuilder strings.Builder @@ -672,7 +666,7 @@ func validateLVMStorageClass( return valid, failedMsgBuilder.String() } -func findUnmanagedDuplicatedSC(scList *v1.StorageClassList, lsc *v1alpha1.LvmStorageClass) string { +func findUnmanagedDuplicatedSC(scList *v1.StorageClassList, lsc *v1alpha1.LVMStorageClass) string { for _, sc := range scList.Items { if sc.Name == lsc.Name && sc.Provisioner != LVMStorageClassProvisioner { return sc.Name @@ -682,7 +676,7 @@ func findUnmanagedDuplicatedSC(scList *v1.StorageClassList, lsc *v1alpha1.LvmSto return "" } -func findAnyThinPool(lsc *v1alpha1.LvmStorageClass) []string { +func findAnyThinPool(lsc *v1alpha1.LVMStorageClass) []string { badLvgs := make([]string, 0, len(lsc.Spec.LVMVolumeGroups)) for _, lvs := range lsc.Spec.LVMVolumeGroups { if lvs.Thin != nil { @@ -693,7 +687,7 @@ func findAnyThinPool(lsc *v1alpha1.LvmStorageClass) []string { return badLvgs } -func findNonexistentThinPools(lvgList *v1alpha1.LvmVolumeGroupList, lsc *v1alpha1.LvmStorageClass) []string { +func findNonexistentThinPools(lvgList *v1alpha1.LvmVolumeGroupList, lsc *v1alpha1.LVMStorageClass) []string { lvgs := make(map[string]v1alpha1.LvmVolumeGroup, len(lvgList.Items)) for _, lvg := range lvgList.Items { lvgs[lvg.Name] = lvg @@ -724,7 +718,7 @@ func findNonexistentThinPools(lvgList *v1alpha1.LvmVolumeGroupList, lsc *v1alpha return badLvgs } -func findNonexistentLVGs(lvgList *v1alpha1.LvmVolumeGroupList, lsc *v1alpha1.LvmStorageClass) []string { +func findNonexistentLVGs(lvgList *v1alpha1.LvmVolumeGroupList, lsc *v1alpha1.LVMStorageClass) []string { lvgs := make(map[string]struct{}, len(lvgList.Items)) for _, lvg := range lvgList.Items { lvgs[lvg.Name] = struct{}{} @@ -740,7 +734,7 @@ func findNonexistentLVGs(lvgList *v1alpha1.LvmVolumeGroupList, lsc *v1alpha1.Lvm return nonexistent } -func findLVMVolumeGroupsOnTheSameNode(lvgList *v1alpha1.LvmVolumeGroupList, lsc *v1alpha1.LvmStorageClass) []string { +func findLVMVolumeGroupsOnTheSameNode(lvgList *v1alpha1.LvmVolumeGroupList, lsc *v1alpha1.LVMStorageClass) []string { nodesWithLVGs := make(map[string][]string, len(lsc.Spec.LVMVolumeGroups)) usedLVGs := make(map[string]struct{}, len(lsc.Spec.LVMVolumeGroups)) for _, lvg := range lsc.Spec.LVMVolumeGroups { @@ -771,7 +765,7 @@ func findLVMVolumeGroupsOnTheSameNode(lvgList *v1alpha1.LvmVolumeGroupList, lsc return badLVGs } -func findOtherDefaultStorageClasses(scList *v1.StorageClassList, lsc *v1alpha1.LvmStorageClass) []string { +func findOtherDefaultStorageClasses(scList *v1.StorageClassList, lsc *v1alpha1.LVMStorageClass) []string { defaults := make([]string, 0, len(scList.Items)) for _, sc := range scList.Items {