From 01d4cb64eab5b40c02ca218543179a9ec1202fee Mon Sep 17 00:00:00 2001 From: "dmitry.lopatin" Date: Fri, 6 Dec 2024 00:46:30 +0300 Subject: [PATCH 1/2] fix Signed-off-by: dmitry.lopatin --- .../pkg/controller/vm/internal/sync_kvvm.go | 133 +--------- .../vm/internal/sync_power_state.go | 241 ++++++++++++++++++ .../pkg/controller/vm/vm_controller.go | 1 + 3 files changed, 243 insertions(+), 132 deletions(-) create mode 100644 images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state.go diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go index c4bf24dc0..c0d10e59b 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go @@ -24,14 +24,12 @@ import ( "time" corev1 "k8s.io/api/core/v1" - k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/tools/record" virtv1 "kubevirt.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" - kvvmutil "github.com/deckhouse/virtualization-controller/pkg/common/kvvm" "github.com/deckhouse/virtualization-controller/pkg/common/object" vmutil "github.com/deckhouse/virtualization-controller/pkg/common/vm" "github.com/deckhouse/virtualization-controller/pkg/controller/conditions" @@ -145,17 +143,10 @@ func (h *SyncKvvmHandler) Handle(ctx context.Context, s state.VirtualMachineStat if synced { // 3.1. Changes are applied, consider current spec as last applied. - lastAppliedSpec = ¤t.Spec changed.Status.RestartAwaitingChanges = nil } - // 4. Ensure power state according to the runPolicy. - powerStateSyncErr := h.syncPowerState(ctx, s, kvvm, lastAppliedSpec) - if powerStateSyncErr != nil { - errs = errors.Join(errs, fmt.Errorf("failed to sync powerstate: %w", powerStateSyncErr)) - } - - // 5. Set ConfigurationApplied condition. + // 4. Set ConfigurationApplied condition. switch { case errs != nil: h.recorder.Event(current, corev1.EventTypeWarning, virtv2.ReasonErrVmNotSynced, kvvmSyncErr.Error()) @@ -542,125 +533,3 @@ func (h *SyncKvvmHandler) updateKVVMLastAppliedSpec(ctx context.Context, vm *vir return nil } - -// syncPowerState enforces runPolicy on the underlying KVVM. -func (h *SyncKvvmHandler) syncPowerState(ctx context.Context, s state.VirtualMachineState, kvvm *virtv1.VirtualMachine, effectiveSpec *virtv2.VirtualMachineSpec) error { - log := logger.FromContext(ctx) - - if kvvm == nil { - return nil - } - - kvvmi, err := s.KVVMI(ctx) - if err != nil { - return fmt.Errorf("find the internal virtual machine instance: %w", err) - } - - vmRunPolicy := effectiveSpec.RunPolicy - var shutdownInfo powerstate.ShutdownInfo - s.Shared(func(s *state.Shared) { - shutdownInfo = s.ShutdownInfo - }) - - switch vmRunPolicy { - case virtv2.AlwaysOffPolicy: - if kvvmi != nil { - // Ensure KVVMI is absent. - err = h.client.Delete(ctx, kvvmi) - if err != nil && !k8serrors.IsNotFound(err) { - return fmt.Errorf("force AlwaysOff: delete KVVMI: %w", err) - } - } - err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyHalted) - case virtv2.AlwaysOnPolicy: - // Power state change reason is not significant for AlwaysOn: - // kubevirt restarts VM via re-creation of KVVMI. - err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyAlways) - case virtv2.AlwaysOnUnlessStoppedManually: - strategy, _ := kvvm.RunStrategy() - if strategy == virtv1.RunStrategyAlways && kvvmi == nil { - if err = powerstate.StartVM(ctx, h.client, kvvm); err != nil { - return fmt.Errorf("failed to start VM: %w", err) - } - } - if kvvmi != nil && kvvmi.DeletionTimestamp == nil { - if kvvmi.Status.Phase == virtv1.Succeeded { - if shutdownInfo.PodCompleted { - // Request to start new KVVMI if guest was restarted. - // Cleanup KVVMI is enough if VM was stopped from inside. - switch shutdownInfo.Reason { - case powerstate.GuestResetReason: - log.Info("Restart for guest initiated reset") - err = powerstate.SafeRestartVM(ctx, h.client, kvvm, kvvmi) - if err != nil { - return fmt.Errorf("restart VM on guest-reset: %w", err) - } - default: - log.Info("Cleanup Succeeded KVVMI") - err = h.client.Delete(ctx, kvvmi) - if err != nil && !k8serrors.IsNotFound(err) { - return fmt.Errorf("delete Succeeded KVVMI: %w", err) - } - } - } - } - if kvvmi.Status.Phase == virtv1.Failed { - log.Info("Restart on Failed KVVMI", "obj", kvvmi.GetName()) - err = powerstate.SafeRestartVM(ctx, h.client, kvvm, kvvmi) - if err != nil { - return fmt.Errorf("restart VM on failed: %w", err) - } - } - } - - err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyManual) - case virtv2.ManualPolicy: - // Manual policy requires to handle only guest-reset event. - // All types of shutdown are a final state. - if kvvmi != nil && kvvmi.DeletionTimestamp == nil { - if kvvmi.Status.Phase == virtv1.Succeeded && shutdownInfo.PodCompleted { - // Request to start new KVVMI (with updated settings). - switch shutdownInfo.Reason { - case powerstate.GuestResetReason: - err = powerstate.SafeRestartVM(ctx, h.client, kvvm, kvvmi) - if err != nil { - return fmt.Errorf("restart VM on guest-reset: %w", err) - } - default: - // Cleanup old version of KVVMI. - log.Info("Cleanup Succeeded KVVMI") - err = h.client.Delete(ctx, kvvmi) - if err != nil && !k8serrors.IsNotFound(err) { - return fmt.Errorf("delete Succeeded KVVMI: %w", err) - } - } - } - } - - err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyManual) - } - - if err != nil { - return fmt.Errorf("enforce runPolicy %s: %w", vmRunPolicy, err) - } - - return nil -} - -func (h *SyncKvvmHandler) ensureRunStrategy(ctx context.Context, kvvm *virtv1.VirtualMachine, desiredRunStrategy virtv1.VirtualMachineRunStrategy) error { - if kvvm == nil { - return nil - } - kvvmRunStrategy := kvvmutil.GetRunStrategy(kvvm) - - if kvvmRunStrategy == desiredRunStrategy { - return nil - } - patch := kvvmutil.PatchRunStrategy(desiredRunStrategy) - err := h.client.Patch(ctx, kvvm, patch) - if err != nil { - return fmt.Errorf("patch KVVM with runStrategy %s: %w", desiredRunStrategy, err) - } - - return nil -} diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state.go b/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state.go new file mode 100644 index 000000000..99d9fbacd --- /dev/null +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state.go @@ -0,0 +1,241 @@ +/* +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 ( + "context" + "fmt" + + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/record" + virtv1 "kubevirt.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + kvvmutil "github.com/deckhouse/virtualization-controller/pkg/common/kvvm" + "github.com/deckhouse/virtualization-controller/pkg/controller/conditions" + "github.com/deckhouse/virtualization-controller/pkg/controller/powerstate" + "github.com/deckhouse/virtualization-controller/pkg/controller/service" + "github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state" + "github.com/deckhouse/virtualization-controller/pkg/logger" + virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2" + "github.com/deckhouse/virtualization/api/core/v1alpha2/vmcondition" +) + +const nameSyncPowerStateHandler = "SyncPowerStateHandler" + +func NewSyncPowerStateHandler(client client.Client, recorder record.EventRecorder) *SyncPowerStateHandler { + return &SyncPowerStateHandler{ + client: client, + recorder: recorder, + } +} + +type SyncPowerStateHandler struct { + client client.Client + recorder record.EventRecorder +} + +func (h *SyncPowerStateHandler) Handle(ctx context.Context, s state.VirtualMachineState) (reconcile.Result, error) { + if s.VirtualMachine().IsEmpty() { + return reconcile.Result{}, nil + } + + current := s.VirtualMachine().Current() + changed := s.VirtualMachine().Changed() + + cbConfApplied := conditions.NewConditionBuilder(vmcondition.TypeConfigurationApplied). + Generation(current.GetGeneration()). + Status(metav1.ConditionUnknown). + Reason(conditions.ReasonUnknown) + + defer func() { + conditions.SetCondition(cbConfApplied, &changed.Status.Conditions) + }() + + kvvm, err := s.KVVM(ctx) + if err != nil { + cbConfApplied. + Status(metav1.ConditionFalse). + Reason(vmcondition.ReasonConfigurationNotApplied). + Message(service.CapitalizeFirstLetter(err.Error()) + ".") + return reconcile.Result{}, err + } + + err = h.syncPowerState(ctx, s, kvvm, &changed.Spec) + if err != nil { + err = fmt.Errorf("failed to sync powerstate: %w", err) + h.recorder.Event(current, corev1.EventTypeWarning, virtv2.ReasonErrVmNotSynced, err.Error()) + cbConfApplied. + Status(metav1.ConditionFalse). + Reason(vmcondition.ReasonConfigurationNotApplied). + Message(service.CapitalizeFirstLetter(err.Error()) + ".") + } + + return reconcile.Result{}, err +} + +// syncPowerState enforces runPolicy on the underlying KVVM. +func (h *SyncPowerStateHandler) syncPowerState(ctx context.Context, s state.VirtualMachineState, kvvm *virtv1.VirtualMachine, effectiveSpec *virtv2.VirtualMachineSpec) error { + log := logger.FromContext(ctx) + + if kvvm == nil { + return nil + } + + kvvmi, err := s.KVVMI(ctx) + if err != nil { + return fmt.Errorf("find the internal virtual machine instance: %w", err) + } + + vmRunPolicy := effectiveSpec.RunPolicy + var shutdownInfo powerstate.ShutdownInfo + s.Shared(func(s *state.Shared) { + shutdownInfo = s.ShutdownInfo + }) + + switch vmRunPolicy { + case virtv2.AlwaysOffPolicy: + if kvvmi != nil { + // Ensure KVVMI is absent. + err = h.client.Delete(ctx, kvvmi) + if err != nil && !k8serrors.IsNotFound(err) { + return fmt.Errorf("force AlwaysOff: delete KVVMI: %w", err) + } + } + err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyHalted) + case virtv2.AlwaysOnPolicy: + strategy, _ := kvvm.RunStrategy() + if strategy == virtv1.RunStrategyAlways && kvvmi == nil { + if err = powerstate.StartVM(ctx, h.client, kvvm); err != nil { + return fmt.Errorf("failed to start VM: %w", err) + } + } + + if kvvmi != nil && kvvmi.DeletionTimestamp == nil { + if kvvmi.Status.Phase == virtv1.Succeeded { + log.Info("Restart for guest initiated reset") + err = powerstate.SafeRestartVM(ctx, h.client, kvvm, kvvmi) + if err != nil { + return fmt.Errorf("restart VM on guest-reset: %w", err) + } + } + + if kvvmi.Status.Phase == virtv1.Failed { + log.Info("Restart on Failed KVVMI", "obj", kvvmi.GetName()) + err = powerstate.SafeRestartVM(ctx, h.client, kvvm, kvvmi) + if err != nil { + return fmt.Errorf("restart VM on failed: %w", err) + } + } + } + + err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyManual) + case virtv2.AlwaysOnUnlessStoppedManually: + strategy, _ := kvvm.RunStrategy() + if strategy == virtv1.RunStrategyAlways && kvvmi == nil { + if err = powerstate.StartVM(ctx, h.client, kvvm); err != nil { + return fmt.Errorf("failed to start VM: %w", err) + } + } + if kvvmi != nil && kvvmi.DeletionTimestamp == nil { + if kvvmi.Status.Phase == virtv1.Succeeded { + if shutdownInfo.PodCompleted { + // Request to start new KVVMI if guest was restarted. + // Cleanup KVVMI is enough if VM was stopped from inside. + switch shutdownInfo.Reason { + case powerstate.GuestResetReason: + log.Info("Restart for guest initiated reset") + err = powerstate.SafeRestartVM(ctx, h.client, kvvm, kvvmi) + if err != nil { + return fmt.Errorf("restart VM on guest-reset: %w", err) + } + default: + log.Info("Cleanup Succeeded KVVMI") + err = h.client.Delete(ctx, kvvmi) + if err != nil && !k8serrors.IsNotFound(err) { + return fmt.Errorf("delete Succeeded KVVMI: %w", err) + } + } + } + } + if kvvmi.Status.Phase == virtv1.Failed { + log.Info("Restart on Failed KVVMI", "obj", kvvmi.GetName()) + err = powerstate.SafeRestartVM(ctx, h.client, kvvm, kvvmi) + if err != nil { + return fmt.Errorf("restart VM on failed: %w", err) + } + } + } + + err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyManual) + case virtv2.ManualPolicy: + // Manual policy requires to handle only guest-reset event. + // All types of shutdown are a final state. + if kvvmi != nil && kvvmi.DeletionTimestamp == nil { + if kvvmi.Status.Phase == virtv1.Succeeded && shutdownInfo.PodCompleted { + // Request to start new KVVMI (with updated settings). + switch shutdownInfo.Reason { + case powerstate.GuestResetReason: + err = powerstate.SafeRestartVM(ctx, h.client, kvvm, kvvmi) + if err != nil { + return fmt.Errorf("restart VM on guest-reset: %w", err) + } + default: + // Cleanup old version of KVVMI. + log.Info("Cleanup Succeeded KVVMI") + err = h.client.Delete(ctx, kvvmi) + if err != nil && !k8serrors.IsNotFound(err) { + return fmt.Errorf("delete Succeeded KVVMI: %w", err) + } + } + } + } + + err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyManual) + } + + if err != nil { + return fmt.Errorf("enforce runPolicy %s: %w", vmRunPolicy, err) + } + + return nil +} + +func (h *SyncPowerStateHandler) ensureRunStrategy(ctx context.Context, kvvm *virtv1.VirtualMachine, desiredRunStrategy virtv1.VirtualMachineRunStrategy) error { + if kvvm == nil { + return nil + } + kvvmRunStrategy := kvvmutil.GetRunStrategy(kvvm) + + if kvvmRunStrategy == desiredRunStrategy { + return nil + } + patch := kvvmutil.PatchRunStrategy(desiredRunStrategy) + err := h.client.Patch(ctx, kvvm, patch) + if err != nil { + return fmt.Errorf("patch KVVM with runStrategy %s: %w", desiredRunStrategy, err) + } + + return nil +} + +func (h *SyncPowerStateHandler) Name() string { + return nameSyncPowerStateHandler +} diff --git a/images/virtualization-artifact/pkg/controller/vm/vm_controller.go b/images/virtualization-artifact/pkg/controller/vm/vm_controller.go index c683a02c1..95f104e5c 100644 --- a/images/virtualization-artifact/pkg/controller/vm/vm_controller.go +++ b/images/virtualization-artifact/pkg/controller/vm/vm_controller.go @@ -63,6 +63,7 @@ func SetupController( internal.NewPodHandler(client), internal.NewSizePolicyHandler(), internal.NewSyncKvvmHandler(dvcrSettings, client, recorder), + internal.NewSyncPowerStateHandler(client, recorder), internal.NewSyncMetadataHandler(client), internal.NewLifeCycleHandler(client, recorder), internal.NewStatisticHandler(client), From 098f8854e87088809c1d7f9649b5cbb6abf71d4d Mon Sep 17 00:00:00 2001 From: "dmitry.lopatin" Date: Fri, 13 Dec 2024 14:58:31 +0300 Subject: [PATCH 2/2] ++ Signed-off-by: dmitry.lopatin --- .../pkg/controller/kvbuilder/kvvm.go | 13 ++---- .../vm/internal/sync_power_state.go | 46 ++++--------------- .../pkg/controller/vm/vm_controller.go | 2 +- 3 files changed, 13 insertions(+), 48 deletions(-) diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go index 3795ecf07..d74815213 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -128,15 +128,10 @@ func (b *KVVM) SetCPUModel(class *virtv2.VirtualMachineClass) error { func (b *KVVM) SetRunPolicy(runPolicy virtv2.RunPolicy) error { switch runPolicy { - case virtv2.AlwaysOnPolicy: - b.Resource.Spec.RunStrategy = pointer.GetPointer(virtv1.RunStrategyAlways) - case virtv2.AlwaysOffPolicy: - b.Resource.Spec.RunStrategy = pointer.GetPointer(virtv1.RunStrategyHalted) - case virtv2.ManualPolicy: - if !b.ResourceExists { - // initialize only - b.Resource.Spec.RunStrategy = pointer.GetPointer(virtv1.RunStrategyManual) - } + case virtv2.AlwaysOnPolicy, + virtv2.AlwaysOffPolicy, + virtv2.ManualPolicy: + b.Resource.Spec.RunStrategy = pointer.GetPointer(virtv1.RunStrategyManual) case virtv2.AlwaysOnUnlessStoppedManually: if !b.ResourceExists { // initialize only diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state.go b/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state.go index 99d9fbacd..ffc0eab5b 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_power_state.go @@ -20,72 +20,48 @@ import ( "context" "fmt" - corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/record" virtv1 "kubevirt.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/reconcile" kvvmutil "github.com/deckhouse/virtualization-controller/pkg/common/kvvm" - "github.com/deckhouse/virtualization-controller/pkg/controller/conditions" "github.com/deckhouse/virtualization-controller/pkg/controller/powerstate" - "github.com/deckhouse/virtualization-controller/pkg/controller/service" "github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state" "github.com/deckhouse/virtualization-controller/pkg/logger" virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2" - "github.com/deckhouse/virtualization/api/core/v1alpha2/vmcondition" ) const nameSyncPowerStateHandler = "SyncPowerStateHandler" -func NewSyncPowerStateHandler(client client.Client, recorder record.EventRecorder) *SyncPowerStateHandler { +func NewSyncPowerStateHandler(client client.Client) *SyncPowerStateHandler { return &SyncPowerStateHandler{ - client: client, - recorder: recorder, + client: client, } } type SyncPowerStateHandler struct { - client client.Client - recorder record.EventRecorder + client client.Client } func (h *SyncPowerStateHandler) Handle(ctx context.Context, s state.VirtualMachineState) (reconcile.Result, error) { + log, ctx := logger.GetHandlerContext(ctx, nameSyncPowerStateHandler) + if s.VirtualMachine().IsEmpty() { return reconcile.Result{}, nil } - current := s.VirtualMachine().Current() changed := s.VirtualMachine().Changed() - cbConfApplied := conditions.NewConditionBuilder(vmcondition.TypeConfigurationApplied). - Generation(current.GetGeneration()). - Status(metav1.ConditionUnknown). - Reason(conditions.ReasonUnknown) - - defer func() { - conditions.SetCondition(cbConfApplied, &changed.Status.Conditions) - }() - kvvm, err := s.KVVM(ctx) if err != nil { - cbConfApplied. - Status(metav1.ConditionFalse). - Reason(vmcondition.ReasonConfigurationNotApplied). - Message(service.CapitalizeFirstLetter(err.Error()) + ".") - return reconcile.Result{}, err + return reconcile.Result{}, fmt.Errorf("find the internal virtual machine: %w", err) } err = h.syncPowerState(ctx, s, kvvm, &changed.Spec) if err != nil { err = fmt.Errorf("failed to sync powerstate: %w", err) - h.recorder.Event(current, corev1.EventTypeWarning, virtv2.ReasonErrVmNotSynced, err.Error()) - cbConfApplied. - Status(metav1.ConditionFalse). - Reason(vmcondition.ReasonConfigurationNotApplied). - Message(service.CapitalizeFirstLetter(err.Error()) + ".") + log.Error(err.Error()) } return reconcile.Result{}, err @@ -119,10 +95,8 @@ func (h *SyncPowerStateHandler) syncPowerState(ctx context.Context, s state.Virt return fmt.Errorf("force AlwaysOff: delete KVVMI: %w", err) } } - err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyHalted) case virtv2.AlwaysOnPolicy: - strategy, _ := kvvm.RunStrategy() - if strategy == virtv1.RunStrategyAlways && kvvmi == nil { + if kvvmi == nil { if err = powerstate.StartVM(ctx, h.client, kvvm); err != nil { return fmt.Errorf("failed to start VM: %w", err) } @@ -145,8 +119,6 @@ func (h *SyncPowerStateHandler) syncPowerState(ctx context.Context, s state.Virt } } } - - err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyManual) case virtv2.AlwaysOnUnlessStoppedManually: strategy, _ := kvvm.RunStrategy() if strategy == virtv1.RunStrategyAlways && kvvmi == nil { @@ -207,8 +179,6 @@ func (h *SyncPowerStateHandler) syncPowerState(ctx context.Context, s state.Virt } } } - - err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyManual) } if err != nil { diff --git a/images/virtualization-artifact/pkg/controller/vm/vm_controller.go b/images/virtualization-artifact/pkg/controller/vm/vm_controller.go index 95f104e5c..10f4dc32f 100644 --- a/images/virtualization-artifact/pkg/controller/vm/vm_controller.go +++ b/images/virtualization-artifact/pkg/controller/vm/vm_controller.go @@ -63,7 +63,7 @@ func SetupController( internal.NewPodHandler(client), internal.NewSizePolicyHandler(), internal.NewSyncKvvmHandler(dvcrSettings, client, recorder), - internal.NewSyncPowerStateHandler(client, recorder), + internal.NewSyncPowerStateHandler(client), internal.NewSyncMetadataHandler(client), internal.NewLifeCycleHandler(client, recorder), internal.NewStatisticHandler(client),