Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ func (h *SyncKvvmHandler) Handle(ctx context.Context, s state.VirtualMachineStat
cbConfApplied.
Status(metav1.ConditionFalse).
Reason(vmcondition.ReasonConfigurationNotApplied).
Message("Waiting for SDN to configure network interfaces on the pod.")
Message("Waiting for SDN to configure network interfaces.")
case kvvmSyncErr != nil:
h.recorder.Event(current, corev1.EventTypeWarning, v1alpha2.ReasonErrVmNotSynced, kvvmSyncErr.Error())
cbConfApplied.
Expand Down Expand Up @@ -777,7 +777,7 @@ func (h *SyncKvvmHandler) applyVMChangesToKVVM(ctx context.Context, s state.Virt
return fmt.Errorf("unable to check pod network status: %w", err)
}
if !ready {
msg := "Waiting for SDN to configure network interfaces on the pod"
msg := "Waiting for SDN to configure network interfaces"
log.Info(msg)
h.recorder.Event(current, corev1.EventTypeNormal, v1alpha2.ReasonVMChangesApplied, msg)
return errWaitForNetworkReady
Expand Down Expand Up @@ -962,7 +962,22 @@ func (h *SyncKvvmHandler) networksOutOfSync(ctx context.Context, s state.Virtual
if kvvm == nil {
return false, nil
}
filteredVM, err := filterReadyNetworks(ctx, s.Client(), s.VirtualMachine().Current())
vm := s.VirtualMachine().Current()
kvvmi, err := s.KVVMI(ctx)
if err != nil {
return false, err
}
// For Main-only VMs, the default pod network may be implicit in the KVVM
// template but explicit in the running VMI: KubeVirt defaulting adds it to
// the VMI spec when the instance starts. If we later "fix" the KVVM template
// from [] to [default] while the VM is already Running, KubeVirt treats that
// template diff as a non-live-updatable network change and sets RestartRequired.
// When there are no active additional interfaces, this is only an implicit-vs-
// explicit default-network drift, so do not reconcile it.
if hasOnlyDefaultNetwork(vm) && !hasActiveAdditionalInterfaces(kvvm) && isKVVMIRunning(kvvmi) {
return false, nil
}
filteredVM, err := filterReadyNetworks(ctx, s.Client(), vm)
if err != nil {
return false, err
}
Expand All @@ -989,7 +1004,45 @@ func (h *SyncKvvmHandler) networksOutOfSync(ctx context.Context, s state.Virtual
return false, nil
}

func isKVVMIRunning(kvvmi *virtv1.VirtualMachineInstance) bool {
return kvvmi != nil && kvvmi.Status.Phase == virtv1.Running
}

func hasActiveAdditionalInterfaces(kvvm *virtv1.VirtualMachine) bool {
if kvvm == nil || kvvm.Spec.Template == nil {
return false
}
for _, iface := range kvvm.Spec.Template.Spec.Domain.Devices.Interfaces {
if iface.Name == network.NameDefaultInterface || iface.State == virtv1.InterfaceStateAbsent {
continue
}
return true
}
return false
}

func (h *SyncKvvmHandler) applyNetworkReadinessSync(ctx context.Context, s state.VirtualMachineState) error {
vm := s.VirtualMachine().Current()
if hasOnlyDefaultNetwork(vm) {
kvvm, err := s.KVVM(ctx)
if err != nil {
return fmt.Errorf("find the internal virtual machine: %w", err)
}
kvvmi, err := s.KVVMI(ctx)
if err != nil {
return fmt.Errorf("find the internal virtual machine instance: %w", err)
}
// For Main-only VMs, KubeVirt may have already defaulted the pod network into
// the running VMI while the KVVM template still has no explicit interfaces.
// Waiting for SDN and updating the template would materialize [] -> [default]
// after the VM is Running, which KubeVirt can report as RestartRequired.
// If there are no active additional interfaces, there is nothing SDN-managed
// to wait for or sync, so skip the network readiness/update path.
if !hasActiveAdditionalInterfaces(kvvm) && isKVVMIRunning(kvvmi) {
return nil
}
}

desired, err := h.patchPodNetworkAnnotation(ctx, s)
if err != nil {
return fmt.Errorf("patch pod network annotation: %w", err)
Expand Down
Loading