Skip to content

Commit

Permalink
feat(vd): block resizing VirtualDisk if storage class not ready (#526)
Browse files Browse the repository at this point in the history
Do not allow resizing operation of VirtualDisk if its StorageClass is not ready.

---------

Signed-off-by: Valeriy Khorunzhin <[email protected]>
  • Loading branch information
eofff authored Nov 25, 2024
1 parent e081e9a commit 0056296
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 26 deletions.
4 changes: 4 additions & 0 deletions images/virtualization-artifact/pkg/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,8 @@ const (
GcVMIMigrationScheduleVar = "GC_VMI_MIGRATION_SCHEDULE"

VmBlockDeviceAttachedLimit = 16

CmpLesser = -1
CmpEqual = 0
CmpGreater = 1
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,10 @@ import (

"k8s.io/apimachinery/pkg/api/resource"

"github.com/deckhouse/virtualization-controller/pkg/common"
virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2"
)

const (
lesser = -1
equal = 0
greater = 1
)

type SizePolicyService struct{}

func NewSizePolicyService() *SizePolicyService {
Expand Down Expand Up @@ -107,7 +102,7 @@ func validateMemory(vm *virtv2.VirtualMachine, sp *virtv2.SizingPolicy) (errorsA
return
}

if vm.Spec.Memory.Size.Cmp(sp.Memory.Min) == lesser {
if vm.Spec.Memory.Size.Cmp(sp.Memory.Min) == common.CmpLesser {
errorsArray = append(errorsArray, fmt.Errorf(
"requested VM memory (%s) is less than the minimum allowed, available range [%s, %s]",
vm.Spec.Memory.Size.String(),
Expand All @@ -116,7 +111,7 @@ func validateMemory(vm *virtv2.VirtualMachine, sp *virtv2.SizingPolicy) (errorsA
))
}

if vm.Spec.Memory.Size.Cmp(sp.Memory.Max) == greater {
if vm.Spec.Memory.Size.Cmp(sp.Memory.Max) == common.CmpGreater {
errorsArray = append(errorsArray, fmt.Errorf(
"requested VM memory (%s) exceeds the maximum allowed, available range [%s, %s]",
vm.Spec.Memory.Size.String(),
Expand Down Expand Up @@ -146,7 +141,7 @@ func validatePerCoreMemory(vm *virtv2.VirtualMachine, sp *virtv2.SizingPolicy) (
vmPerCore := vm.Spec.Memory.Size.Value() / int64(vm.Spec.CPU.Cores)
perCoreMemory := resource.NewQuantity(vmPerCore, resource.BinarySI)

if perCoreMemory.Cmp(sp.Memory.PerCore.Min) == lesser {
if perCoreMemory.Cmp(sp.Memory.PerCore.Min) == common.CmpLesser {
errorsArray = append(errorsArray, fmt.Errorf(
"requested VM per core memory (%s) is less than the minimum allowed, available range [%s, %s]",
perCoreMemory.String(),
Expand All @@ -155,7 +150,7 @@ func validatePerCoreMemory(vm *virtv2.VirtualMachine, sp *virtv2.SizingPolicy) (
))
}

if perCoreMemory.Cmp(sp.Memory.PerCore.Max) == greater {
if perCoreMemory.Cmp(sp.Memory.PerCore.Max) == common.CmpGreater {
errorsArray = append(errorsArray, fmt.Errorf(
"requested VM per core memory (%s) exceeds the maximum allowed, available range [%s, %s]",
perCoreMemory.String(),
Expand All @@ -181,9 +176,9 @@ func validateIsQuantized(value, min, max, step resource.Quantity, source string)
cmpLeftResult := value.Cmp(grid[i])
cmpRightResult := value.Cmp(grid[i+1])

if cmpLeftResult == equal || cmpRightResult == equal {
if cmpLeftResult == common.CmpEqual || cmpRightResult == common.CmpEqual {
return
} else if cmpLeftResult == greater && cmpRightResult == lesser {
} else if cmpLeftResult == common.CmpGreater && cmpRightResult == common.CmpLesser {
err = fmt.Errorf(
"requested %s does not match any available values, nearest valid values are [%s, %s]",
source,
Expand All @@ -200,7 +195,7 @@ func validateIsQuantized(value, min, max, step resource.Quantity, source string)
func generateValidGrid(min, max, step resource.Quantity) []resource.Quantity {
var grid []resource.Quantity

for val := min; val.Cmp(max) == lesser; val.Add(step) {
for val := min; val.Cmp(max) == common.CmpLesser; val.Add(step) {
grid = append(grid, val)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

"github.com/deckhouse/virtualization-controller/pkg/controller/common"
"github.com/deckhouse/virtualization-controller/pkg/common"
cc "github.com/deckhouse/virtualization-controller/pkg/controller/common"
"github.com/deckhouse/virtualization-controller/pkg/controller/conditions"
"github.com/deckhouse/virtualization-controller/pkg/controller/service"
"github.com/deckhouse/virtualization-controller/pkg/controller/supplements"
Expand Down Expand Up @@ -69,7 +70,7 @@ func (h ResizingHandler) Handle(ctx context.Context, vd *virtv2.VirtualDisk) (re
return reconcile.Result{}, nil
}

supgen := supplements.NewGenerator(common.VDShortName, vd.Name, vd.Namespace, vd.UID)
supgen := supplements.NewGenerator(cc.VDShortName, vd.Name, vd.Namespace, vd.UID)
pvc, err := h.diskService.GetPersistentVolumeClaim(ctx, supgen)
if err != nil {
return reconcile.Result{}, err
Expand Down Expand Up @@ -112,8 +113,10 @@ func (h ResizingHandler) Handle(ctx context.Context, vd *virtv2.VirtualDisk) (re
return reconcile.Result{}, nil
}

storageClassReadyCondition, _ := conditions.GetCondition(vdcondition.StorageClassReadyType, vd.Status.Conditions)

// Expected disk size is GREATER THAN expected pvc size: resize needed, resizing to a larger size.
if vdSpecSize != nil && vdSpecSize.Cmp(pvcSpecSize) == 1 {
if vdSpecSize != nil && vdSpecSize.Cmp(pvcSpecSize) == common.CmpGreater {
snapshotting, _ := conditions.GetCondition(vdcondition.SnapshottingType, vd.Status.Conditions)
if snapshotting.Status == metav1.ConditionTrue {
cb.
Expand All @@ -123,16 +126,29 @@ func (h ResizingHandler) Handle(ctx context.Context, vd *virtv2.VirtualDisk) (re
return reconcile.Result{}, nil
}

err = h.diskService.Resize(ctx, pvc, *vdSpecSize)
if err != nil {
if k8serrors.IsForbidden(err) {
cb.
Status(metav1.ConditionFalse).
Reason(vdcondition.ResizingNotAvailable).
Message(fmt.Sprintf("Disk resizing is not allowed: %s.", err.Error()))
return reconcile.Result{}, nil
switch storageClassReadyCondition.Status {
case metav1.ConditionTrue:
err = h.diskService.Resize(ctx, pvc, *vdSpecSize)
if err != nil {
if k8serrors.IsForbidden(err) {
cb.
Status(metav1.ConditionFalse).
Reason(vdcondition.ResizingNotAvailable).
Message(fmt.Sprintf("Disk resizing is not allowed: %s.", err.Error()))
return reconcile.Result{}, nil
}
return reconcile.Result{}, err
}
return reconcile.Result{}, err
case metav1.ConditionFalse:
cb.
Status(metav1.ConditionFalse).
Reason(vdcondition.ResizingNotRequested).
Message("Disk resizing is not allowed: Storage class is not ready")
case metav1.ConditionUnknown:
cb.
Status(metav1.ConditionUnknown).
Reason(conditions.ReasonUnknown).
Message("")
}

log.Info("The virtual disk resizing has started")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ var _ = Describe("Resizing handler Run", func() {
Type: vdcondition.ReadyType.String(),
Status: metav1.ConditionTrue,
},
{
Type: vdcondition.StorageClassReadyType.String(),
Status: metav1.ConditionTrue,
},
},
Capacity: size.String(),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

"github.com/deckhouse/virtualization-controller/pkg/common"
"github.com/deckhouse/virtualization-controller/pkg/controller"
"github.com/deckhouse/virtualization-controller/pkg/controller/conditions"
"github.com/deckhouse/virtualization-controller/pkg/controller/service"
Expand Down Expand Up @@ -140,7 +141,7 @@ func (v *PVCSizeValidator) ValidateUpdate(ctx context.Context, oldVD, newVD *vir
}

if ready.Status == metav1.ConditionTrue || newVD.Status.Phase != virtv2.DiskPending && newVD.Status.Phase != virtv2.DiskProvisioning {
if newSize.Cmp(oldSize) == -1 {
if newSize.Cmp(oldSize) == common.CmpLesser {
return nil, fmt.Errorf(
"spec.persistentVolumeClaim.size value (%s) should be greater than or equal to the current value (%s)",
newSize.String(),
Expand Down

0 comments on commit 0056296

Please sign in to comment.