Skip to content

Commit

Permalink
feat(vm): Add Events about power state changes
Browse files Browse the repository at this point in the history
- Also duplicate these events in log.

Signed-off-by: Ivan Mikheykin <[email protected]>
  • Loading branch information
diafour committed Dec 9, 2024
1 parent dc64fc2 commit d493620
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 23 deletions.
10 changes: 8 additions & 2 deletions api/core/v1alpha2/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,14 @@ const (
// ReasonVMChangesApplied is event reason that changes applied from VM to underlying KVVM.
ReasonVMChangesApplied = "ChangesApplied"

// ReasonVMRestarted is event reason that VM restarted.
ReasonVMRestarted = "VMRestarted"
// ReasonVMStart is event reason that VM is about to start.
ReasonVMStart = "Start"

// ReasonVMStop is event reason that VM is about to stop.
ReasonVMStop = "Stop"

// ReasonVMRestart is event reason that VM is about to restart.
ReasonVMRestart = "Restart"

// ReasonVMLastAppliedSpecInvalid is event reason that JSON in last-applied-spec annotation is invalid.
ReasonVMLastAppliedSpecInvalid = "VMLastAppliedSpecInvalid"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (

corev1 "k8s.io/api/core/v1"
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"
Expand All @@ -35,14 +34,15 @@ import (
"github.com/deckhouse/virtualization-controller/pkg/controller/kvbuilder"
"github.com/deckhouse/virtualization-controller/pkg/controller/service"
"github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state"
"github.com/deckhouse/virtualization-controller/pkg/eventrecord"
"github.com/deckhouse/virtualization-controller/pkg/logger"
virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2"
"github.com/deckhouse/virtualization/api/core/v1alpha2/vmcondition"
)

const nameBlockDeviceHandler = "BlockDeviceHandler"

func NewBlockDeviceHandler(cl client.Client, recorder record.EventRecorder) *BlockDeviceHandler {
func NewBlockDeviceHandler(cl client.Client, recorder eventrecord.EventRecorderLogger) *BlockDeviceHandler {
return &BlockDeviceHandler{
client: cl,
recorder: recorder,
Expand All @@ -55,7 +55,7 @@ func NewBlockDeviceHandler(cl client.Client, recorder record.EventRecorder) *Blo

type BlockDeviceHandler struct {
client client.Client
recorder record.EventRecorder
recorder eventrecord.EventRecorderLogger

viProtection *service.ProtectionService
cviProtection *service.ProtectionService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ import (

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/record"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

"github.com/deckhouse/virtualization-controller/pkg/controller/conditions"
"github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state"
"github.com/deckhouse/virtualization-controller/pkg/eventrecord"
"github.com/deckhouse/virtualization-controller/pkg/logger"
virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2"
"github.com/deckhouse/virtualization/api/core/v1alpha2/vmcondition"
)

const nameClassHandler = "ClassHandler"

func NewClassHandler(client client.Client, recorder record.EventRecorder) *ClassHandler {
func NewClassHandler(client client.Client, recorder eventrecord.EventRecorderLogger) *ClassHandler {
return &ClassHandler{
client: client,
recorder: recorder,
Expand All @@ -45,7 +45,7 @@ func NewClassHandler(client client.Client, recorder record.EventRecorder) *Class

type ClassHandler struct {
client client.Client
recorder record.EventRecorder
recorder eventrecord.EventRecorderLogger
}

func (h *ClassHandler) Handle(ctx context.Context, s state.VirtualMachineState) (reconcile.Result, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (

corev1 "k8s.io/api/core/v1"
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"
Expand All @@ -33,6 +32,7 @@ import (
"github.com/deckhouse/virtualization-controller/pkg/controller/kvbuilder"
"github.com/deckhouse/virtualization-controller/pkg/controller/service"
"github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state"
"github.com/deckhouse/virtualization-controller/pkg/eventrecord"
"github.com/deckhouse/virtualization-controller/pkg/logger"
virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2"
"github.com/deckhouse/virtualization/api/core/v1alpha2/vmcondition"
Expand All @@ -46,7 +46,7 @@ type IPAM interface {
CreateIPAddress(ctx context.Context, vm *virtv2.VirtualMachine, client client.Client) error
}

func NewIPAMHandler(ipam IPAM, cl client.Client, recorder record.EventRecorder) *IPAMHandler {
func NewIPAMHandler(ipam IPAM, cl client.Client, recorder eventrecord.EventRecorderLogger) *IPAMHandler {
return &IPAMHandler{
ipam: ipam,
client: cl,
Expand All @@ -58,7 +58,7 @@ func NewIPAMHandler(ipam IPAM, cl client.Client, recorder record.EventRecorder)
type IPAMHandler struct {
ipam IPAM
client client.Client
recorder record.EventRecorder
recorder eventrecord.EventRecorderLogger
protection *service.ProtectionService
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (

corev1 "k8s.io/api/core/v1"
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"
Expand All @@ -32,6 +31,7 @@ import (
"github.com/deckhouse/virtualization-controller/pkg/controller/conditions"
"github.com/deckhouse/virtualization-controller/pkg/controller/service"
"github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state"
"github.com/deckhouse/virtualization-controller/pkg/eventrecord"
"github.com/deckhouse/virtualization-controller/pkg/logger"
virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2"
"github.com/deckhouse/virtualization/api/core/v1alpha2/vmcondition"
Expand All @@ -46,13 +46,13 @@ var lifeCycleConditions = []vmcondition.Type{

const nameLifeCycleHandler = "LifeCycleHandler"

func NewLifeCycleHandler(client client.Client, recorder record.EventRecorder) *LifeCycleHandler {
func NewLifeCycleHandler(client client.Client, recorder eventrecord.EventRecorderLogger) *LifeCycleHandler {
return &LifeCycleHandler{client: client, recorder: recorder}
}

type LifeCycleHandler struct {
client client.Client
recorder record.EventRecorder
recorder eventrecord.EventRecorderLogger
}

func (h *LifeCycleHandler) Handle(ctx context.Context, s state.VirtualMachineState) (reconcile.Result, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
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"
Expand All @@ -41,14 +40,15 @@ import (
"github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal/state"
"github.com/deckhouse/virtualization-controller/pkg/controller/vmchange"
"github.com/deckhouse/virtualization-controller/pkg/dvcr"
"github.com/deckhouse/virtualization-controller/pkg/eventrecord"
"github.com/deckhouse/virtualization-controller/pkg/logger"
virtv2 "github.com/deckhouse/virtualization/api/core/v1alpha2"
"github.com/deckhouse/virtualization/api/core/v1alpha2/vmcondition"
)

const nameSyncKvvmHandler = "SyncKvvmHandler"

func NewSyncKvvmHandler(dvcrSettings *dvcr.Settings, client client.Client, recorder record.EventRecorder) *SyncKvvmHandler {
func NewSyncKvvmHandler(dvcrSettings *dvcr.Settings, client client.Client, recorder eventrecord.EventRecorderLogger) *SyncKvvmHandler {
return &SyncKvvmHandler{
dvcrSettings: dvcrSettings,
client: client,
Expand All @@ -58,7 +58,7 @@ func NewSyncKvvmHandler(dvcrSettings *dvcr.Settings, client client.Client, recor

type SyncKvvmHandler struct {
client client.Client
recorder record.EventRecorder
recorder eventrecord.EventRecorderLogger
dvcrSettings *dvcr.Settings
}

Expand Down Expand Up @@ -489,7 +489,7 @@ func (h *SyncKvvmHandler) applyVMChangesToKVVM(ctx context.Context, s state.Virt
log.Info("Restart VM to apply changes", "vm.name", current.GetName())

h.recorder.Event(current, corev1.EventTypeNormal, virtv2.ReasonVMChangesApplied, "Apply disruptive changes")
h.recorder.Event(current, corev1.EventTypeNormal, virtv2.ReasonVMRestarted, "")
h.recorder.Event(current, corev1.EventTypeNormal, virtv2.ReasonVMRestart, "")

// Update KVVM spec according the current VM spec.
if err = h.updateKVVM(ctx, s); err != nil {
Expand Down Expand Up @@ -568,7 +568,7 @@ func (h *SyncKvvmHandler) syncPowerState(ctx context.Context, s state.VirtualMac
// 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)
return fmt.Errorf("automatic stop VM for %s policy: delete KVVMI: %w", vmRunPolicy, err)
}
}
err = h.ensureRunStrategy(ctx, kvvm, virtv1.RunStrategyHalted)
Expand All @@ -580,7 +580,7 @@ func (h *SyncKvvmHandler) syncPowerState(ctx context.Context, s state.VirtualMac
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)
return fmt.Errorf("automatic start VM for %s policy: %w", vmRunPolicy, err)
}
}
if kvvmi != nil && kvvmi.DeletionTimestamp == nil {
Expand All @@ -605,10 +605,23 @@ func (h *SyncKvvmHandler) syncPowerState(ctx context.Context, s state.VirtualMac
}
}
if kvvmi.Status.Phase == virtv1.Failed {
log.Info("Restart on Failed KVVMI", "obj", kvvmi.GetName())
//h.recorder.WithLogging(log).RecordEvent(&eventrecord.Event{
// InvolvedObject: s.VirtualMachine().Current(),
// Type: corev1.EventTypeNormal,
// Reason: "Restart",
// Message: fmt.Sprintf("Restart initiated by controller for %s runPolicy after observing failed VM instance", vmRunPolicy)),
//})
h.recorder.WithLogging(log).Eventf(
s.VirtualMachine().Current(),
corev1.EventTypeNormal,
virtv2.ReasonVMRestart,
"Restart initiated by controller for %s runPolicy after observing failed VM instance",
vmRunPolicy,
)

err = powerstate.SafeRestartVM(ctx, h.client, kvvm, kvvmi)
if err != nil {
return fmt.Errorf("restart VM on failed: %w", err)
return fmt.Errorf("automatic restart of Failed VM: %w", err)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ import (
"sigs.k8s.io/controller-runtime/pkg/metrics"

"github.com/deckhouse/deckhouse/pkg/log"

"github.com/deckhouse/virtualization-controller/pkg/controller/ipam"
"github.com/deckhouse/virtualization-controller/pkg/controller/service"
"github.com/deckhouse/virtualization-controller/pkg/controller/vm/internal"
"github.com/deckhouse/virtualization-controller/pkg/dvcr"
"github.com/deckhouse/virtualization-controller/pkg/eventrecord"
"github.com/deckhouse/virtualization-controller/pkg/logger"
vmmetrics "github.com/deckhouse/virtualization-controller/pkg/monitoring/metrics/virtualmachine"
"github.com/deckhouse/virtualization/api/core/v1alpha2"
Expand All @@ -47,7 +49,7 @@ func SetupController(
dvcrSettings *dvcr.Settings,
) error {
log := lg.With(logger.SlogController(controllerName))
recorder := mgr.GetEventRecorderFor(controllerName)
recorder := eventrecord.NewEventRecorderLogger(mgr.GetEventRecorderFor(controllerName))
mgrCache := mgr.GetCache()
client := mgr.GetClient()
blockDeviceService := service.NewBlockDeviceService(client)
Expand Down
49 changes: 49 additions & 0 deletions images/virtualization-artifact/pkg/eventrecord/event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package eventrecord

import (
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type Event struct {
// The object that this event is about.
InvolvedObject client.Object

// The top object that this event is related to. E.g. VirtualMachine for VirtualMachineOperation.
// Only for logging, will not be reflected in the Event resource.
RelatedObject client.Object

// Type of this event (Normal, Warning), new types could be added in the future
Type string

// This should be a short, machine understandable string that gives the reason
// for the transition into the object's current status.
Reason string

// A human-readable description of the status of this operation.
Message string
}

func NewNormalEvent(involvedObject client.Object, reason, message string) *Event {
return &Event{
InvolvedObject: involvedObject,
Type: corev1.EventTypeNormal,
Reason: reason,
Message: message,
}
}

func NewWarningEvent(involvedObject client.Object, reason, message string) *Event {
return &Event{
InvolvedObject: involvedObject,
Type: corev1.EventTypeWarning,
Reason: reason,
Message: message,
}
}

func NewNormalEventWithRelated(involvedObject client.Object, relatedObject client.Object, reason, message string) *Event {
ev := NewNormalEvent(involvedObject, reason, message)
ev.RelatedObject = relatedObject
return ev
}
Loading

0 comments on commit d493620

Please sign in to comment.