vm-import-controller/pkg/controllers/migration/helper.go
Gaurav Mehta 40948a8ba9
work around to reconcile vm images more effectively (#16)
simplify disk condition checks

convert disk image status reconcile into a wrapper

move VM reconcile to a wrapper method

move preflight checks to a wrapper

more wrappers
2023-08-04 13:04:29 +08:00

132 lines
4.1 KiB
Go

package migration
import (
"reflect"
"time"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
migration "github.com/harvester/vm-import-controller/pkg/apis/migration.harvesterhci.io/v1beta1"
"github.com/harvester/vm-import-controller/pkg/util"
)
func evaluateDiskImportStatus(diskImportStatus []migration.DiskInfo) *migration.ImportStatus {
ok := true
failed := false
var failedCount, passedCount int
for _, d := range diskImportStatus {
ok = util.ConditionExists(d.DiskConditions, migration.VirtualMachineImageReady, v1.ConditionTrue) && ok
if ok {
passedCount++
}
failed = util.ConditionExists(d.DiskConditions, migration.VirtualMachineImageFailed, v1.ConditionTrue) || failed
if failed {
failedCount++
}
}
if len(diskImportStatus) != failedCount+passedCount {
// if length's dont match, then we have disks with missing status. Lets ignore failures for now, and handle
// disk failures once we have had watches triggered for all disks
return nil
}
if ok {
return &[]migration.ImportStatus{migration.DiskImagesReady}[0]
}
if failed {
return &[]migration.ImportStatus{migration.DiskImagesFailed}[0]
}
return nil
}
func (h *virtualMachineHandler) reconcileDiskImageStatus(vm *migration.VirtualMachineImport) (*migration.VirtualMachineImport, error) {
orgStatus := vm.Status.DeepCopy()
// If VM has no disks associated ignore the VM
if len(orgStatus.DiskImportStatus) == 0 {
logrus.Errorf("Imported VM %s in namespace %s, has no disks, being marked as invalid and will be ignored", vm.Name, vm.Namespace)
vm.Status.Status = migration.VirtualMachineInvalid
return h.importVM.UpdateStatus(vm)
}
err := h.createVirtualMachineImages(vm)
if err != nil {
// check if any disks have been updated. We need to save this info to eventually reconcile the VMI creation
var newVM *migration.VirtualMachineImport
var newErr error
if !reflect.DeepEqual(orgStatus.DiskImportStatus, vm.Status.DiskImportStatus) {
newVM, newErr = h.importVM.UpdateStatus(vm)
}
if newErr != nil {
logrus.Errorf("error updating status for vm status %s: %v", vm.Name, newErr)
}
return newVM, err
}
ok := true
for _, d := range vm.Status.DiskImportStatus {
ok = util.ConditionExists(d.DiskConditions, migration.VirtualMachineImageSubmitted, v1.ConditionTrue) && ok
}
if ok {
vm.Status.Status = migration.DiskImagesSubmitted
}
return h.importVM.UpdateStatus(vm)
}
func (h *virtualMachineHandler) reconcileVirtualMachineStatus(vm *migration.VirtualMachineImport) (*migration.VirtualMachineImport, error) {
// wait for VM to be running using a watch on VM's
ok, err := h.checkVirtualMachine(vm)
if err != nil {
return vm, err
}
if !ok {
// VM not running, requeue and check after 5mins
h.importVM.EnqueueAfter(vm.Namespace, vm.Name, 5*time.Minute)
return vm, nil
}
vm.Status.Status = migration.VirtualMachineRunning
return h.importVM.UpdateStatus(vm)
}
func (h *virtualMachineHandler) reconcilePreFlightChecks(vm *migration.VirtualMachineImport) (*migration.VirtualMachineImport, error) {
err := h.preFlightChecks(vm)
if err != nil {
if err.Error() != migration.NotValidDNS1123Label {
return vm, err
}
logrus.Errorf("vm migration target %s in VM %s in namespace %s is not RFC 1123 compliant", vm.Spec.VirtualMachineName, vm.Name, vm.Namespace)
vm.Status.Status = migration.VirtualMachineInvalid
} else {
vm.Status.Status = migration.SourceReady
}
return h.importVM.UpdateStatus(vm)
}
func (h *virtualMachineHandler) runVirtualMachineExport(vm *migration.VirtualMachineImport) (*migration.VirtualMachineImport, error) {
err := h.triggerExport(vm)
if err != nil {
return vm, err
}
if util.ConditionExists(vm.Status.ImportConditions, migration.VirtualMachineExported, v1.ConditionTrue) {
vm.Status.Status = migration.DisksExported
}
return h.importVM.UpdateStatus(vm)
}
func (h *virtualMachineHandler) triggerResubmit(vm *migration.VirtualMachineImport) (*migration.VirtualMachineImport, error) {
// re-export VM and trigger re-import again
err := h.cleanupAndResubmit(vm)
if err != nil {
return vm, err
}
vm.Status.Status = migration.SourceReady
return h.importVM.UpdateStatus(vm)
}