Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

Validate template memory requirements #406

Merged
merged 1 commit into from Sep 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/providers/ovirt/provider.go
Expand Up @@ -263,7 +263,7 @@ func (o *OvirtProvider) Validate() ([]v2vv1.VirtualMachineImportCondition, error
return []v2vv1.VirtualMachineImportCondition{}, errors.New("VM has not been loaded")
}
vmiName := o.GetVmiNamespacedName()
return o.validator.Validate(vm, &vmiName, o.resourceMapping), nil
return o.validator.Validate(vm, &vmiName, o.resourceMapping, o.templateFinder), nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about not retrieving the template twice and refactoring into something along these lines?:

  • retrieve template in the controller before validation - set it on provider;
  • in provider pass the template to validation (instead of the template finder) and
    • check whether the template was found (if required) - I think we talked about making it part of validation, not processing;
    • check the memory requirements.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have been thinking about it but we handle the template differently in both places. As well as we would always fetched it but in some cases validation would fail so it wouldn't be needed.

}

// StopVM stop the source VM on ovirt
Expand Down
3 changes: 2 additions & 1 deletion pkg/providers/ovirt/validation/mocks_test.go
Expand Up @@ -2,6 +2,7 @@ package validation_test

import (
v2vv1 "github.com/kubevirt/vm-import-operator/pkg/apis/v2v/v1beta1"
otemplates "github.com/kubevirt/vm-import-operator/pkg/providers/ovirt/templates"
validators "github.com/kubevirt/vm-import-operator/pkg/providers/ovirt/validation/validators"
ovirtsdk "github.com/ovirt/go-ovirt"
)
Expand All @@ -18,7 +19,7 @@ var validateStorageMappingMock func(

type mockValidator struct{}

func (v *mockValidator) ValidateVM(vm *ovirtsdk.Vm) []validators.ValidationFailure {
func (v *mockValidator) ValidateVM(vm *ovirtsdk.Vm, finder *otemplates.TemplateFinder) []validators.ValidationFailure {
return validateVMMock(vm)
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/providers/ovirt/validation/validators/definitions.go
Expand Up @@ -77,6 +77,8 @@ const (
VMMemoryPolicyOvercommitPercentID = CheckID("vm.memory_policy.over_commit.percent")
// VMMemoryPolicyGuaranteedID defines an ID of a vm.memory_policy.guaranteed check
VMMemoryPolicyGuaranteedID = CheckID("vm.memory_policy.guaranteed")
// VMMemoryTemplateLimitID defines that vm memory is below template requirements
VMMemoryTemplateLimitID = CheckID("vm.memory template.requests")
// VMMigrationID defines an ID of a vm.migration check
VMMigrationID = CheckID("vm.migration")
// VMMigrationDowntimeID defines an ID of a vm.migration_downtime check
Expand Down
Expand Up @@ -3,6 +3,7 @@ package validators
import (
v2vv1 "github.com/kubevirt/vm-import-operator/pkg/apis/v2v/v1beta1"
kvConfig "github.com/kubevirt/vm-import-operator/pkg/config/kubevirt"
otemplates "github.com/kubevirt/vm-import-operator/pkg/providers/ovirt/templates"
ovirtsdk "github.com/ovirt/go-ovirt"
"sigs.k8s.io/controller-runtime/pkg/client"
logf "sigs.k8s.io/controller-runtime/pkg/log"
Expand Down Expand Up @@ -33,12 +34,12 @@ func NewValidatorWrapper(client client.Client, kvConfigProvider kvConfig.KubeVir
}

// ValidateVM wraps validators package implementation of ValidateVM function
func (v *ValidatorWrapper) ValidateVM(vm *ovirtsdk.Vm) []ValidationFailure {
func (v *ValidatorWrapper) ValidateVM(vm *ovirtsdk.Vm, finder *otemplates.TemplateFinder) []ValidationFailure {
kvConfig, err := v.kvConfigProvider.GetConfig()
if err != nil {
logger.Error(err, "Cannot get KubeVirt cluster config.")
}
return ValidateVM(vm, kvConfig)
return ValidateVM(vm, kvConfig, finder)
}

// ValidateDiskStatus return true if the disk status is valid:
Expand Down
31 changes: 30 additions & 1 deletion pkg/providers/ovirt/validation/validators/vm-validator.go
@@ -1,19 +1,22 @@
package validators

import (
"encoding/json"
"fmt"

kvConfig "github.com/kubevirt/vm-import-operator/pkg/config/kubevirt"

"github.com/kubevirt/vm-import-operator/pkg/utils"

"github.com/kubevirt/vm-import-operator/pkg/providers/ovirt/mapper"
otemplates "github.com/kubevirt/vm-import-operator/pkg/providers/ovirt/templates"
outils "github.com/kubevirt/vm-import-operator/pkg/providers/ovirt/utils"
ovirtsdk "github.com/ovirt/go-ovirt"
kubevirtv1 "kubevirt.io/client-go/api/v1"
)

// ValidateVM validates given VM
func ValidateVM(vm *ovirtsdk.Vm, config kvConfig.KubeVirtConfig) []ValidationFailure {
func ValidateVM(vm *ovirtsdk.Vm, config kvConfig.KubeVirtConfig, finder *otemplates.TemplateFinder) []ValidationFailure {
var results = isValidBios(vm)
if failure, valid := isValidStatus(vm); !valid {
results = append(results, failure)
Expand Down Expand Up @@ -89,6 +92,9 @@ func ValidateVM(vm *ovirtsdk.Vm, config kvConfig.KubeVirtConfig) []ValidationFai
if failure, valid := isValidFloppies(vm); !valid {
results = append(results, failure)
}
if failure, valid := isMemoryAboveRequests(vm, finder); !valid {
results = append(results, failure)
}

return results
}
Expand All @@ -113,6 +119,29 @@ func isValidBios(vm *ovirtsdk.Vm) []ValidationFailure {
return results
}

func isMemoryAboveRequests(vm *ovirtsdk.Vm, finder *otemplates.TemplateFinder) (ValidationFailure, bool) {
template, err := finder.FindTemplate(vm)
if err != nil {
// missing template is verified later
return ValidationFailure{}, true
}
tempVM := kubevirtv1.VirtualMachine{}
err = json.Unmarshal(template.Objects[0].Raw, &tempVM)
if err != nil {
// template processed later
return ValidationFailure{}, true
}
tempMem, tok := tempVM.Spec.Template.Spec.Domain.Resources.Requests.Memory().AsInt64()
sourceMem, sok := vm.Memory()
if tok && sok && tempMem > sourceMem {
return ValidationFailure{
ID: VMMemoryTemplateLimitID,
Message: fmt.Sprintf("Source VM memory is lower than enforced by template."),
}, false
}
return ValidationFailure{}, true
}

func isValidStatus(vm *ovirtsdk.Vm) (ValidationFailure, bool) {
if status, ok := vm.Status(); ok {
if status != ovirtsdk.VMSTATUS_UP && status != ovirtsdk.VMSTATUS_DOWN {
Expand Down