Skip to content

Commit

Permalink
fix(vd): fix fake pvc resizing
Browse files Browse the repository at this point in the history
Signed-off-by: Isteb4k <dmitry.rakitin@flant.com>
  • Loading branch information
Isteb4k committed Jun 26, 2024
1 parent 72230c7 commit 0264f46
Show file tree
Hide file tree
Showing 8 changed files with 380 additions and 139 deletions.
2 changes: 0 additions & 2 deletions api/core/v1alpha2/vdcondition/condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ const (
NotRequested ResizedReason = "NotRequested"
// InProgress indicates that the resize request has been detected and the operation is currently in progress.
InProgress ResizedReason = "InProgress"
// TooSmallDiskSize indicates that the requested disk size is too small for the resize operation.
TooSmallDiskSize ResizedReason = "TooSmallDiskSize"
// Resized indicates that the resize operation has been successfully completed.
Resized ResizedReason = "Resized"
)
Original file line number Diff line number Diff line change
Expand Up @@ -166,22 +166,20 @@ func (s DiskService) Unprotect(ctx context.Context, dv *cdiv1.DataVolume) error
return s.protection.RemoveProtection(ctx, dv)
}

func (s DiskService) Resize(ctx context.Context, pvc *corev1.PersistentVolumeClaim, newSize resource.Quantity, sup *supplements.Generator) error {
func (s DiskService) Resize(ctx context.Context, pvc *corev1.PersistentVolumeClaim, newSize resource.Quantity) error {
if pvc == nil {
return errors.New("got nil pvc")
}

curSize := pvc.Spec.Resources.Requests[corev1.ResourceStorage]

if newSize.Cmp(curSize) == -1 {
return ErrTooSmallDiskSize
return nil
}

switch newSize.Cmp(curSize) {
case 0:
case 0, -1:
return nil
case -1:
return ErrTooSmallDiskSize
default:
pvc.Spec.Resources.Requests[corev1.ResourceStorage] = newSize

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ package service

import "errors"

var ErrTooSmallDiskSize = errors.New("virtual disk size is too small")

var (
ErrStorageClassNotFound = errors.New("storage class not found")
ErrDefaultStorageClassNotFound = errors.New("default storage class not found")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
Copyright 2024 Flant JSC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package internal

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestHandlers(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Handlers")
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,25 @@ limitations under the License.
package internal

import (
"context"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"

"github.com/deckhouse/virtualization-controller/pkg/controller/supplements"
"github.com/deckhouse/virtualization-controller/pkg/controller/vd/internal/source"
virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2"
)

//go:generate moq -rm -out mock.go . Handler Sources
//go:generate moq -rm -out mock.go . Handler Sources DiskService

type Handler = source.Handler

type Sources interface {
Get(dsType virtv2.DataSourceType) (source.Handler, bool)
}

type DiskService interface {
Resize(ctx context.Context, pvc *corev1.PersistentVolumeClaim, newSize resource.Quantity) error
GetPersistentVolumeClaim(ctx context.Context, sup *supplements.Generator) (*corev1.PersistentVolumeClaim, error)
}
131 changes: 131 additions & 0 deletions images/virtualization-artifact/pkg/controller/vd/internal/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"errors"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

Expand All @@ -32,10 +33,10 @@ import (
)

type ResizingHandler struct {
diskService *service.DiskService
diskService DiskService
}

func NewResizingHandler(diskService *service.DiskService) *ResizingHandler {
func NewResizingHandler(diskService DiskService) *ResizingHandler {
return &ResizingHandler{
diskService: diskService,
}
Expand All @@ -59,8 +60,8 @@ func (h ResizingHandler) Handle(ctx context.Context, vd *virtv2.VirtualDisk) (re
return reconcile.Result{}, nil
}

newSize := vd.Spec.PersistentVolumeClaim.Size
if newSize == nil {
vdSpecSize := vd.Spec.PersistentVolumeClaim.Size
if vdSpecSize == nil {
condition.Status = metav1.ConditionFalse
condition.Reason = vdcondition.NotRequested
condition.Message = ""
Expand All @@ -85,33 +86,57 @@ func (h ResizingHandler) Handle(ctx context.Context, vd *virtv2.VirtualDisk) (re
return reconcile.Result{}, errors.New("pvc not found for ready virtual disk")
}

if newSize.Equal(pvc.Status.Capacity[corev1.ResourceStorage]) {
if condition.Reason == vdcondition.InProgress {
condition.Status = metav1.ConditionTrue
condition.Reason = vdcondition.Resized
condition.Message = ""
return reconcile.Result{}, nil
}

pvcSpecSize := pvc.Spec.Resources.Requests[corev1.ResourceStorage]
switch vdSpecSize.Cmp(pvcSpecSize) {
// Expected disk size is LESS THAN expected pvc size: no resize needed as resizing to a smaller size is not possible.
case -1:
condition.Status = metav1.ConditionFalse
condition.Reason = vdcondition.NotRequested
condition.Message = ""
return reconcile.Result{}, nil
}
// Expected disk size is GREATER THAN expected pvc size: resize needed, resizing to a larger size.
case 1:
err = h.diskService.Resize(ctx, pvc, *vdSpecSize)
if err != nil {
return reconcile.Result{}, err
}

err = h.diskService.Resize(ctx, pvc, *newSize, supgen)
switch {
case err == nil:
condition.Status = metav1.ConditionFalse
condition.Reason = vdcondition.InProgress
condition.Message = "The virtual disk is in the process of resizing."
return reconcile.Result{}, nil
case errors.Is(err, service.ErrTooSmallDiskSize):
// Expected disk size is EQUAL TO expected pvc size: cannot definitively say whether the resize has already happened or was not needed - perform additional checks.
case 0:
}

var vdStatusSize resource.Quantity
vdStatusSize, err = resource.ParseQuantity(vd.Status.Capacity)
if err != nil {
return reconcile.Result{}, err
}

pvcStatusSize := pvc.Status.Capacity[corev1.ResourceStorage]

// Expected pvc size is GREATER THAN actual pvc size: resize has been requested and is in progress.
if pvcSpecSize.Cmp(pvcStatusSize) == 1 {
condition.Status = metav1.ConditionFalse
condition.Reason = vdcondition.TooSmallDiskSize
condition.Message = "The new size of the virtual disk must not be smaller than the current size."
condition.Reason = vdcondition.InProgress
condition.Message = "The virtual disk is in the process of resizing."
return reconcile.Result{}, nil
default:
return reconcile.Result{}, err
}

// Virtual disk size DOES NOT MATCH pvc size: resize has completed, synchronize the virtual disk size.
if !vdStatusSize.Equal(pvcStatusSize) {
vd.Status.Capacity = pvcStatusSize.String()
condition.Status = metav1.ConditionTrue
condition.Reason = vdcondition.Resized
condition.Message = ""
return reconcile.Result{}, nil
}

// Expected pvc size is NOT GREATER THAN actual PVC size AND virtual disk size MATCHES pvc size: resize was not requested.
condition.Status = metav1.ConditionFalse
condition.Reason = vdcondition.NotRequested
condition.Message = ""
return reconcile.Result{}, nil
}
Loading

0 comments on commit 0264f46

Please sign in to comment.