From 56cc73b58ec160397f31aea447ea0e8487fc7ce1 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 14 Apr 2026 15:23:15 +0300 Subject: [PATCH 01/36] feat(vm): add disable-tap-veth-bridge setting Signed-off-by: Dmitry Lopatin --- .../cmd/virtualization-controller/main.go | 4 ++- .../pkg/common/annotations/annotations.go | 2 ++ .../pkg/config/load_network_settings.go | 31 +++++++++++++++++++ .../pkg/controller/kvbuilder/kvvm.go | 5 +++ .../pkg/controller/kvbuilder/kvvm_utils.go | 5 +++ .../controller/vm/internal/migrating_test.go | 2 +- .../vm/internal/service/migration_volumes.go | 22 +++++++------ .../pkg/controller/vm/internal/sync_kvvm.go | 30 ++++++++++-------- .../controller/vm/internal/sync_kvvm_test.go | 2 +- .../pkg/controller/vm/vm_controller.go | 6 ++-- openapi/config-values.yaml | 13 ++++++++ .../virtualization-controller/_helpers.tpl | 2 ++ 12 files changed, 95 insertions(+), 29 deletions(-) create mode 100644 images/virtualization-artifact/pkg/config/load_network_settings.go diff --git a/images/virtualization-artifact/cmd/virtualization-controller/main.go b/images/virtualization-artifact/cmd/virtualization-controller/main.go index f134d49e3a..453148ce87 100644 --- a/images/virtualization-artifact/cmd/virtualization-controller/main.go +++ b/images/virtualization-artifact/cmd/virtualization-controller/main.go @@ -208,6 +208,8 @@ func main() { os.Exit(1) } + networkSettings := appconfig.LoadNetworkSettingsFromEnv() + // Get a config to talk to the apiserver cfg, err := config.GetConfig() if err != nil { @@ -360,7 +362,7 @@ func main() { } vmLogger := logger.NewControllerLogger(vm.ControllerName, logLevel, logOutput, logDebugVerbosity, logDebugControllerList) - if err = vm.SetupController(ctx, mgr, virtClient, vmLogger, dvcrSettings, firmwareImage, controllerNamespace); err != nil { + if err = vm.SetupController(ctx, mgr, virtClient, vmLogger, dvcrSettings, firmwareImage, controllerNamespace, networkSettings.DisableTapVethBridge); err != nil { log.Error(err.Error()) os.Exit(1) } diff --git a/images/virtualization-artifact/pkg/common/annotations/annotations.go b/images/virtualization-artifact/pkg/common/annotations/annotations.go index a487cab2b2..c9143b5cae 100644 --- a/images/virtualization-artifact/pkg/common/annotations/annotations.go +++ b/images/virtualization-artifact/pkg/common/annotations/annotations.go @@ -88,6 +88,8 @@ const ( // AnnVMRestartRequested is an annotation on KVVM that represents a request to restart a virtual machine. AnnVMRestartRequested = AnnAPIGroupV + "/vm-restart-requested" + // AnnDisableTapVethBridge disables tap-veth-bridge wiring for the VMI network setup in KubeVirt. + AnnDisableTapVethBridge = AnnAPIGroupV + "/disable-tap-veth-bridge" // AnnVMOPWorkloadUpdate is an annotation on vmop that represents a vmop created by workload-updater controller. AnnVMOPWorkloadUpdate = AnnAPIGroupV + "/workload-update" diff --git a/images/virtualization-artifact/pkg/config/load_network_settings.go b/images/virtualization-artifact/pkg/config/load_network_settings.go new file mode 100644 index 0000000000..762ad89e66 --- /dev/null +++ b/images/virtualization-artifact/pkg/config/load_network_settings.go @@ -0,0 +1,31 @@ +/* +Copyright 2026 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 config + +import "os" + +const DisableTapVethBridgeVar = "DISABLE_TAP_VETH_BRIDGE" + +type NetworkSettings struct { + DisableTapVethBridge bool +} + +func LoadNetworkSettingsFromEnv() NetworkSettings { + return NetworkSettings{ + DisableTapVethBridge: os.Getenv(DisableTapVethBridgeVar) == "true", + } +} diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go index 68cb1793a6..e9fe0e3ba1 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -68,6 +68,7 @@ const ( type KVVMOptions struct { EnableParavirtualization bool OsType v1alpha2.OsType + DisableTapVethBridge bool // These options are for local development mode DisableHypervSyNIC bool @@ -93,6 +94,10 @@ func DefaultOptions(current *v1alpha2.VirtualMachine) KVVMOptions { } } +func (b *KVVM) Options() KVVMOptions { + return b.opts +} + func NewEmptyKVVM(name types.NamespacedName, opts KVVMOptions) *KVVM { return &KVVM{ opts: opts, diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go index ba54337ff7..31c3fc956e 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go @@ -117,6 +117,11 @@ func ApplyVirtualMachineSpec( kvvm.SetUSBMigrationStrategy() kvvm.SetMetadata(vm.ObjectMeta) + if kvvm.Options().DisableTapVethBridge { + kvvm.SetKVVMIAnnotation(annotations.AnnDisableTapVethBridge, "true") + } else { + kvvm.RemoveKVVMIAnnotation(annotations.AnnDisableTapVethBridge) + } setNetwork(kvvm, networkSpec) kvvm.SetTablet("default-0") kvvm.SetNodeSelector(vm.Spec.NodeSelector, class.Spec.NodeSelector.MatchLabels) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go index 6eef76e17f..0ac7bbc788 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go @@ -92,7 +92,7 @@ var _ = Describe("MigratingHandler", func() { } reconcile := func() { - h := NewMigratingHandler(vmservice.NewMigrationVolumesService(fakeClient, MakeKVVMFromVMSpec, 10*time.Second)) + h := NewMigratingHandler(vmservice.NewMigrationVolumesService(fakeClient, MakeKVVMFromVMSpec, 10*time.Second, false)) _, err := h.Handle(ctx, vmState) Expect(err).NotTo(HaveOccurred()) err = resource.Update(context.Background()) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go b/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go index 4193c8affc..080b901068 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go @@ -47,18 +47,20 @@ import ( ) type MigrationVolumesService struct { - client client.Client - makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState) (*virtv1.VirtualMachine, error) - delay map[types.UID]time.Time - delayDuration time.Duration + client client.Client + makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool) (*virtv1.VirtualMachine, error) + delay map[types.UID]time.Time + delayDuration time.Duration + disableTapVethBridge bool } -func NewMigrationVolumesService(client client.Client, makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState) (*virtv1.VirtualMachine, error), delayDuration time.Duration) *MigrationVolumesService { +func NewMigrationVolumesService(client client.Client, makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool) (*virtv1.VirtualMachine, error), delayDuration time.Duration, disableTapVethBridge bool) *MigrationVolumesService { return &MigrationVolumesService{ - client: client, - makeKVVMFromSpec: makeKVVMFromSpec, - delay: make(map[types.UID]time.Time), - delayDuration: delayDuration, + client: client, + makeKVVMFromSpec: makeKVVMFromSpec, + delay: make(map[types.UID]time.Time), + delayDuration: delayDuration, + disableTapVethBridge: disableTapVethBridge, } } @@ -479,7 +481,7 @@ func (s MigrationVolumesService) fillContainerDiskImagePullPolicies(kvvm *virtv1 } func (s MigrationVolumesService) makeKVVMFromVirtualMachineSpec(ctx context.Context, vmState state.VirtualMachineState) (*virtv1.VirtualMachine, *virtv1.VirtualMachine, error) { - kvvm, err := s.makeKVVMFromSpec(ctx, vmState) + kvvm, err := s.makeKVVMFromSpec(ctx, vmState, s.disableTapVethBridge) if err != nil { return nil, nil, err } 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 688b0f556d..a4bb850b20 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go @@ -63,22 +63,25 @@ func NewSyncKvvmHandler( recorder eventrecord.EventRecorderLogger, featureGate featuregate.FeatureGate, syncVolumesService syncVolumesService, + disableTapVethBridge bool, ) *SyncKvvmHandler { return &SyncKvvmHandler{ - dvcrSettings: dvcrSettings, - client: client, - recorder: recorder, - featureGate: featureGate, - syncVolumesService: syncVolumesService, + dvcrSettings: dvcrSettings, + client: client, + recorder: recorder, + featureGate: featureGate, + syncVolumesService: syncVolumesService, + disableTapVethBridge: disableTapVethBridge, } } type SyncKvvmHandler struct { - client client.Client - recorder eventrecord.EventRecorderLogger - dvcrSettings *dvcr.Settings - featureGate featuregate.FeatureGate - syncVolumesService syncVolumesService + client client.Client + recorder eventrecord.EventRecorderLogger + dvcrSettings *dvcr.Settings + featureGate featuregate.FeatureGate + syncVolumesService syncVolumesService + disableTapVethBridge bool } func (h *SyncKvvmHandler) Handle(ctx context.Context, s state.VirtualMachineState) (reconcile.Result, error) { @@ -353,7 +356,7 @@ func (h *SyncKvvmHandler) createKVVM(ctx context.Context, s state.VirtualMachine if s.VirtualMachine().IsEmpty() { return fmt.Errorf("the virtual machine is empty, please report a bug") } - kvvm, err := MakeKVVMFromVMSpec(ctx, s) + kvvm, err := MakeKVVMFromVMSpec(ctx, s, h.disableTapVethBridge) if err != nil { return fmt.Errorf("failed to make the internal virtual machine: %w", err) } @@ -382,7 +385,7 @@ func (h *SyncKvvmHandler) updateKVVM(ctx context.Context, s state.VirtualMachine return fmt.Errorf("the virtual machine is empty, please report a bug") } - newKVVM, err := MakeKVVMFromVMSpec(ctx, s) + newKVVM, err := MakeKVVMFromVMSpec(ctx, s, h.disableTapVethBridge) if err != nil { return fmt.Errorf("update internal virtual machine: make kvvm from the virtual machine spec: %w", err) } @@ -448,7 +451,7 @@ func saveKVVMDomainMemoryForPatching(prevKVVM, newKVVM *virtv1.VirtualMachine) * return nil } -func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState) (*virtv1.VirtualMachine, error) { +func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool) (*virtv1.VirtualMachine, error) { if s.VirtualMachine().IsEmpty() { return nil, nil } @@ -456,6 +459,7 @@ func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState) (*virt kvvmName := object.NamespacedName(current) kvvmOpts := kvbuilder.DefaultOptions(current) + kvvmOpts.DisableTapVethBridge = disableTapVethBridge kvvm, err := s.KVVM(ctx) if err != nil { diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm_test.go index 1e76e42ee3..5073ede77a 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm_test.go @@ -138,7 +138,7 @@ var _ = Describe("SyncKvvmHandler", func() { } reconcile := func() { - h := NewSyncKvvmHandler(nil, fakeClient, recorder, featuregates.Default(), vmservice.NewMigrationVolumesService(fakeClient, MakeKVVMFromVMSpec, 10*time.Second)) + h := NewSyncKvvmHandler(nil, fakeClient, recorder, featuregates.Default(), vmservice.NewMigrationVolumesService(fakeClient, MakeKVVMFromVMSpec, 10*time.Second, false), false) _, err := h.Handle(ctx, vmState) Expect(err).NotTo(HaveOccurred()) err = resource.Update(context.Background()) diff --git a/images/virtualization-artifact/pkg/controller/vm/vm_controller.go b/images/virtualization-artifact/pkg/controller/vm/vm_controller.go index ebc466e99e..01bbbdacd0 100644 --- a/images/virtualization-artifact/pkg/controller/vm/vm_controller.go +++ b/images/virtualization-artifact/pkg/controller/vm/vm_controller.go @@ -52,6 +52,7 @@ func SetupController( dvcrSettings *dvcr.Settings, firmwareImage string, controllerNamespace string, + disableTapVethBridge bool, ) error { recorder := eventrecord.NewEventRecorderLogger(mgr, ControllerName) mgrCache := mgr.GetCache() @@ -60,7 +61,7 @@ func SetupController( vmClassService := service.NewVirtualMachineClassService(client) attachmentService := service.NewAttachmentService(client, virtClient, controllerNamespace) - migrateVolumesService := vmservice.NewMigrationVolumesService(client, internal.MakeKVVMFromVMSpec, 10*time.Second) + migrateVolumesService := vmservice.NewMigrationVolumesService(client, internal.MakeKVVMFromVMSpec, 10*time.Second, disableTapVethBridge) handlers := []Handler{ internal.NewMaintenanceHandler(client), @@ -78,8 +79,7 @@ func SetupController( internal.NewPodHandler(client), internal.NewSizePolicyHandler(), internal.NewNetworkInterfaceHandler(featuregates.Default()), - internal.NewSyncKvvmHandler(dvcrSettings, client, recorder, featuregates.Default(), migrateVolumesService), - internal.NewHotplugHandler(attachmentService), + internal.NewSyncKvvmHandler(dvcrSettings, client, recorder, featuregates.Default(), migrateVolumesService, disableTapVethBridge), internal.NewSyncPowerStateHandler(client, recorder), internal.NewSyncMetadataHandler(client), internal.NewLifeCycleHandler(client, recorder), diff --git a/openapi/config-values.yaml b/openapi/config-values.yaml index e46d2362fc..3ded848587 100644 --- a/openapi/config-values.yaml +++ b/openapi/config-values.yaml @@ -252,6 +252,19 @@ properties: type: string minLength: 1 x-examples: ["sc-1", "sc-2"] + network: + type: object + description: | + Virtual machine networking settings. + properties: + disableTapVethBridge: + type: boolean + default: false + description: | + Disable tap-veth-bridge wiring for KubeVirt bridge interfaces. + + When enabled, the virtualization controller adds the `virtualization.deckhouse.io/disable-tap-veth-bridge=true` annotation to the KubeVirt VirtualMachineInstance template. + The KubeVirt network setup then skips creating the tap-veth-bridge wiring and bridge DHCP configurator for such VMIs. logLevel: type: string description: | diff --git a/templates/virtualization-controller/_helpers.tpl b/templates/virtualization-controller/_helpers.tpl index 3d799bf0fd..220c3a020c 100644 --- a/templates/virtualization-controller/_helpers.tpl +++ b/templates/virtualization-controller/_helpers.tpl @@ -18,6 +18,8 @@ true value: "1" - name: DISABLE_HYPERV_SYNIC value: "1" +- name: DISABLE_TAP_VETH_BRIDGE + value: {{ dig "network" "disableTapVethBridge" false .Values.virtualization.internal.moduleConfig | toString | quote }} - name: POD_NAMESPACE valueFrom: fieldRef: From 79e0e9bc91ac1376ccec4180304dfba691bbfecf Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 6 May 2026 20:17:40 +0300 Subject: [PATCH 02/36] wip Signed-off-by: Dmitry Lopatin --- build/components/versions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/components/versions.yml b/build/components/versions.yml index a22d26fe03..69b9475ef1 100644 --- a/build/components/versions.yml +++ b/build/components/versions.yml @@ -3,7 +3,7 @@ firmware: libvirt: v10.9.0 edk2: stable202411 core: - 3p-kubevirt: v1.6.2-v12n.34 + 3p-kubevirt: feat/vm/disable-tap-veth-bridge 3p-containerized-data-importer: v1.60.3-v12n.19 distribution: 2.8.3 package: From 690f3e293d92629050c821e977583ece96c0053d Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Thu, 16 Apr 2026 22:30:14 +0300 Subject: [PATCH 03/36] feat(vm): add disable DHCP VM setting Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 ++ .../pkg/common/annotations/annotations.go | 2 ++ .../pkg/config/load_network_settings.go | 3 +++ .../pkg/controller/kvbuilder/kvvm.go | 1 + .../pkg/controller/kvbuilder/kvvm_utils.go | 5 +++++ .../pkg/controller/vm/internal/migrating_test.go | 2 +- .../vm/internal/service/migration_volumes.go | 8 +++++--- .../pkg/controller/vm/internal/sync_kvvm.go | 10 +++++++--- .../pkg/controller/vm/internal/sync_kvvm_test.go | 2 +- .../pkg/controller/vm/vm_controller.go | 5 +++-- openapi/config-values.yaml | 8 ++++++++ templates/virtualization-controller/_helpers.tpl | 2 ++ 12 files changed, 40 insertions(+), 10 deletions(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 6381ba5eae..3838d60e76 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -13,8 +13,10 @@ secrets: - id: SOURCE_REPO value: {{ $.SOURCE_REPO }} shell: + installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | + echo "$date" echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt diff --git a/images/virtualization-artifact/pkg/common/annotations/annotations.go b/images/virtualization-artifact/pkg/common/annotations/annotations.go index c9143b5cae..b318f95bc7 100644 --- a/images/virtualization-artifact/pkg/common/annotations/annotations.go +++ b/images/virtualization-artifact/pkg/common/annotations/annotations.go @@ -90,6 +90,8 @@ const ( AnnVMRestartRequested = AnnAPIGroupV + "/vm-restart-requested" // AnnDisableTapVethBridge disables tap-veth-bridge wiring for the VMI network setup in KubeVirt. AnnDisableTapVethBridge = AnnAPIGroupV + "/disable-tap-veth-bridge" + // AnnDisableDHCP disables bridge DHCP configurator for the VMI network setup in KubeVirt. + AnnDisableDHCP = AnnAPIGroupV + "/disable-dhcp" // AnnVMOPWorkloadUpdate is an annotation on vmop that represents a vmop created by workload-updater controller. AnnVMOPWorkloadUpdate = AnnAPIGroupV + "/workload-update" diff --git a/images/virtualization-artifact/pkg/config/load_network_settings.go b/images/virtualization-artifact/pkg/config/load_network_settings.go index 762ad89e66..1bf35cbd94 100644 --- a/images/virtualization-artifact/pkg/config/load_network_settings.go +++ b/images/virtualization-artifact/pkg/config/load_network_settings.go @@ -19,13 +19,16 @@ package config import "os" const DisableTapVethBridgeVar = "DISABLE_TAP_VETH_BRIDGE" +const DisableDHCPVar = "DISABLE_DHCP" type NetworkSettings struct { DisableTapVethBridge bool + DisableDHCP bool } func LoadNetworkSettingsFromEnv() NetworkSettings { return NetworkSettings{ DisableTapVethBridge: os.Getenv(DisableTapVethBridgeVar) == "true", + DisableDHCP: os.Getenv(DisableDHCPVar) == "true", } } diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go index e9fe0e3ba1..95f8e5c2e5 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -69,6 +69,7 @@ type KVVMOptions struct { EnableParavirtualization bool OsType v1alpha2.OsType DisableTapVethBridge bool + DisableDHCP bool // These options are for local development mode DisableHypervSyNIC bool diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go index 31c3fc956e..df93e6729d 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go @@ -122,6 +122,11 @@ func ApplyVirtualMachineSpec( } else { kvvm.RemoveKVVMIAnnotation(annotations.AnnDisableTapVethBridge) } + if kvvm.Options().DisableDHCP { + kvvm.SetKVVMIAnnotation(annotations.AnnDisableDHCP, "true") + } else { + kvvm.RemoveKVVMIAnnotation(annotations.AnnDisableDHCP) + } setNetwork(kvvm, networkSpec) kvvm.SetTablet("default-0") kvvm.SetNodeSelector(vm.Spec.NodeSelector, class.Spec.NodeSelector.MatchLabels) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go index 0ac7bbc788..fe6a704abd 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/migrating_test.go @@ -92,7 +92,7 @@ var _ = Describe("MigratingHandler", func() { } reconcile := func() { - h := NewMigratingHandler(vmservice.NewMigrationVolumesService(fakeClient, MakeKVVMFromVMSpec, 10*time.Second, false)) + h := NewMigratingHandler(vmservice.NewMigrationVolumesService(fakeClient, MakeKVVMFromVMSpec, 10*time.Second, false, false)) _, err := h.Handle(ctx, vmState) Expect(err).NotTo(HaveOccurred()) err = resource.Update(context.Background()) diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go b/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go index 080b901068..f1370e7eb3 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go @@ -48,19 +48,21 @@ import ( type MigrationVolumesService struct { client client.Client - makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool) (*virtv1.VirtualMachine, error) + makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool, disableDHCP bool) (*virtv1.VirtualMachine, error) delay map[types.UID]time.Time delayDuration time.Duration disableTapVethBridge bool + disableDHCP bool } -func NewMigrationVolumesService(client client.Client, makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool) (*virtv1.VirtualMachine, error), delayDuration time.Duration, disableTapVethBridge bool) *MigrationVolumesService { +func NewMigrationVolumesService(client client.Client, makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool, disableDHCP bool) (*virtv1.VirtualMachine, error), delayDuration time.Duration, disableTapVethBridge bool, disableDHCP bool) *MigrationVolumesService { return &MigrationVolumesService{ client: client, makeKVVMFromSpec: makeKVVMFromSpec, delay: make(map[types.UID]time.Time), delayDuration: delayDuration, disableTapVethBridge: disableTapVethBridge, + disableDHCP: disableDHCP, } } @@ -481,7 +483,7 @@ func (s MigrationVolumesService) fillContainerDiskImagePullPolicies(kvvm *virtv1 } func (s MigrationVolumesService) makeKVVMFromVirtualMachineSpec(ctx context.Context, vmState state.VirtualMachineState) (*virtv1.VirtualMachine, *virtv1.VirtualMachine, error) { - kvvm, err := s.makeKVVMFromSpec(ctx, vmState, s.disableTapVethBridge) + kvvm, err := s.makeKVVMFromSpec(ctx, vmState, s.disableTapVethBridge, s.disableDHCP) if err != nil { return nil, nil, err } 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 a4bb850b20..c2cc61804d 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go @@ -64,6 +64,7 @@ func NewSyncKvvmHandler( featureGate featuregate.FeatureGate, syncVolumesService syncVolumesService, disableTapVethBridge bool, + disableDHCP bool, ) *SyncKvvmHandler { return &SyncKvvmHandler{ dvcrSettings: dvcrSettings, @@ -72,6 +73,7 @@ func NewSyncKvvmHandler( featureGate: featureGate, syncVolumesService: syncVolumesService, disableTapVethBridge: disableTapVethBridge, + disableDHCP: disableDHCP, } } @@ -82,6 +84,7 @@ type SyncKvvmHandler struct { featureGate featuregate.FeatureGate syncVolumesService syncVolumesService disableTapVethBridge bool + disableDHCP bool } func (h *SyncKvvmHandler) Handle(ctx context.Context, s state.VirtualMachineState) (reconcile.Result, error) { @@ -356,7 +359,7 @@ func (h *SyncKvvmHandler) createKVVM(ctx context.Context, s state.VirtualMachine if s.VirtualMachine().IsEmpty() { return fmt.Errorf("the virtual machine is empty, please report a bug") } - kvvm, err := MakeKVVMFromVMSpec(ctx, s, h.disableTapVethBridge) + kvvm, err := MakeKVVMFromVMSpec(ctx, s, h.disableTapVethBridge, h.disableDHCP) if err != nil { return fmt.Errorf("failed to make the internal virtual machine: %w", err) } @@ -385,7 +388,7 @@ func (h *SyncKvvmHandler) updateKVVM(ctx context.Context, s state.VirtualMachine return fmt.Errorf("the virtual machine is empty, please report a bug") } - newKVVM, err := MakeKVVMFromVMSpec(ctx, s, h.disableTapVethBridge) + newKVVM, err := MakeKVVMFromVMSpec(ctx, s, h.disableTapVethBridge, h.disableDHCP) if err != nil { return fmt.Errorf("update internal virtual machine: make kvvm from the virtual machine spec: %w", err) } @@ -451,7 +454,7 @@ func saveKVVMDomainMemoryForPatching(prevKVVM, newKVVM *virtv1.VirtualMachine) * return nil } -func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool) (*virtv1.VirtualMachine, error) { +func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool, disableDHCP bool) (*virtv1.VirtualMachine, error) { if s.VirtualMachine().IsEmpty() { return nil, nil } @@ -460,6 +463,7 @@ func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState, disabl kvvmOpts := kvbuilder.DefaultOptions(current) kvvmOpts.DisableTapVethBridge = disableTapVethBridge + kvvmOpts.DisableDHCP = disableDHCP kvvm, err := s.KVVM(ctx) if err != nil { diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm_test.go b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm_test.go index 5073ede77a..a288a73dc2 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm_test.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm_test.go @@ -138,7 +138,7 @@ var _ = Describe("SyncKvvmHandler", func() { } reconcile := func() { - h := NewSyncKvvmHandler(nil, fakeClient, recorder, featuregates.Default(), vmservice.NewMigrationVolumesService(fakeClient, MakeKVVMFromVMSpec, 10*time.Second, false), false) + h := NewSyncKvvmHandler(nil, fakeClient, recorder, featuregates.Default(), vmservice.NewMigrationVolumesService(fakeClient, MakeKVVMFromVMSpec, 10*time.Second, false, false), false, false) _, err := h.Handle(ctx, vmState) Expect(err).NotTo(HaveOccurred()) err = resource.Update(context.Background()) diff --git a/images/virtualization-artifact/pkg/controller/vm/vm_controller.go b/images/virtualization-artifact/pkg/controller/vm/vm_controller.go index 01bbbdacd0..0fdc33291e 100644 --- a/images/virtualization-artifact/pkg/controller/vm/vm_controller.go +++ b/images/virtualization-artifact/pkg/controller/vm/vm_controller.go @@ -53,6 +53,7 @@ func SetupController( firmwareImage string, controllerNamespace string, disableTapVethBridge bool, + disableDHCP bool, ) error { recorder := eventrecord.NewEventRecorderLogger(mgr, ControllerName) mgrCache := mgr.GetCache() @@ -61,7 +62,7 @@ func SetupController( vmClassService := service.NewVirtualMachineClassService(client) attachmentService := service.NewAttachmentService(client, virtClient, controllerNamespace) - migrateVolumesService := vmservice.NewMigrationVolumesService(client, internal.MakeKVVMFromVMSpec, 10*time.Second, disableTapVethBridge) + migrateVolumesService := vmservice.NewMigrationVolumesService(client, internal.MakeKVVMFromVMSpec, 10*time.Second, disableTapVethBridge, disableDHCP) handlers := []Handler{ internal.NewMaintenanceHandler(client), @@ -79,7 +80,7 @@ func SetupController( internal.NewPodHandler(client), internal.NewSizePolicyHandler(), internal.NewNetworkInterfaceHandler(featuregates.Default()), - internal.NewSyncKvvmHandler(dvcrSettings, client, recorder, featuregates.Default(), migrateVolumesService, disableTapVethBridge), + internal.NewSyncKvvmHandler(dvcrSettings, client, recorder, featuregates.Default(), migrateVolumesService, disableTapVethBridge, disableDHCP), internal.NewSyncPowerStateHandler(client, recorder), internal.NewSyncMetadataHandler(client), internal.NewLifeCycleHandler(client, recorder), diff --git a/openapi/config-values.yaml b/openapi/config-values.yaml index 3ded848587..1e42890ff3 100644 --- a/openapi/config-values.yaml +++ b/openapi/config-values.yaml @@ -265,6 +265,14 @@ properties: When enabled, the virtualization controller adds the `virtualization.deckhouse.io/disable-tap-veth-bridge=true` annotation to the KubeVirt VirtualMachineInstance template. The KubeVirt network setup then skips creating the tap-veth-bridge wiring and bridge DHCP configurator for such VMIs. + disableDHCP: + type: boolean + default: false + description: | + Disable bridge DHCP configurator for KubeVirt bridge interfaces. + + When enabled, the virtualization controller adds the `virtualization.deckhouse.io/disable-dhcp=true` annotation to the KubeVirt VirtualMachineInstance template. + The KubeVirt network setup then skips creating the bridge DHCP configurator for such VMIs. logLevel: type: string description: | diff --git a/templates/virtualization-controller/_helpers.tpl b/templates/virtualization-controller/_helpers.tpl index 220c3a020c..626efadf66 100644 --- a/templates/virtualization-controller/_helpers.tpl +++ b/templates/virtualization-controller/_helpers.tpl @@ -20,6 +20,8 @@ true value: "1" - name: DISABLE_TAP_VETH_BRIDGE value: {{ dig "network" "disableTapVethBridge" false .Values.virtualization.internal.moduleConfig | toString | quote }} +- name: DISABLE_DHCP + value: {{ dig "network" "disableDHCP" false .Values.virtualization.internal.moduleConfig | toString | quote }} - name: POD_NAMESPACE valueFrom: fieldRef: From fa3c17f38c35e0579fd25a233d4d0ae341d0835e Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 28 Apr 2026 23:56:56 +0300 Subject: [PATCH 04/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 3838d60e76..c77d688c0d 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -199,7 +199,12 @@ shell: {{- include "image-build.build" (set $ "BuildCommand" `go build -ldflags="-s -w" -o /kubevirt-binaries/virt-operator ./cmd/virt-operator/`) | nindent 6 }} - echo ============== Build sidecars ========================= - {{- $_ := set $ "ProjectName" (list .ImageName "sidecars" | join "/") }} + - | + cd /kubevirt + echo "Sidecars cmd list:" + ls -la cmd/sidecars/ + echo "---" + {{- $_ := set $ "ProjectName" (list $.ImageName "sidecars" | join "/") }} - | {{- include "image-build.build" (set $ "BuildCommand" `go build -ldflags="-s -w" -o /kubevirt-binaries/sidecars ./cmd/sidecars/`) | nindent 6 }} From 04ea5d630af8fc84bd7ae205de8ffa49c98a8d42 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 15:00:43 +0300 Subject: [PATCH 05/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index c77d688c0d..84a599556d 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date" + echo "$date -- " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From 4f06ece981435428db764e970679fa429f895db1 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 20:15:05 +0300 Subject: [PATCH 06/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 5 +++++ images/virt-launcher/werf.inc.yaml | 1 + 2 files changed, 6 insertions(+) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 84a599556d..89ce7c6935 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -208,6 +208,11 @@ shell: - | {{- include "image-build.build" (set $ "BuildCommand" `go build -ldflags="-s -w" -o /kubevirt-binaries/sidecars ./cmd/sidecars/`) | nindent 6 }} + - echo ============== Build network-bpf-bridge-binding ======= + {{- $_ := set $ "ProjectName" (list $.ImageName "network-bpf-bridge-binding" | join "/") }} + - | + {{- include "image-build.build" (set $ "BuildCommand" `go build -ldflags="-s -w" -o /kubevirt-binaries/network-bpf-bridge-binding ./cmd/sidecars/network-bpf-bridge-binding/`) | nindent 6 }} + - echo ============== Build virtctl ========================== {{- $_ := set $ "ProjectName" (list .ImageName "virtctl" | join "/") }} - | diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index 89dcb3dceb..106a0116d4 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -196,6 +196,7 @@ import: before: setup includePaths: - container-disk + - network-bpf-bridge-binding - virt-freezer - virt-launcher - virt-launcher-monitor From b54761956d04eb4e99f31df5f653ae8db3d2dd12 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 20:49:25 +0300 Subject: [PATCH 07/36] wip Signed-off-by: Dmitry Lopatin --- templates/kubevirt/kubevirt.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/templates/kubevirt/kubevirt.yaml b/templates/kubevirt/kubevirt.yaml index 31656db4cc..a869cac786 100644 --- a/templates/kubevirt/kubevirt.yaml +++ b/templates/kubevirt/kubevirt.yaml @@ -39,6 +39,11 @@ spec: {{- end }} evictionStrategy: LiveMigrate vmRolloutStrategy: LiveUpdate + network: + binding: + bpfbridge: + sidecarImage: {{ include "helm_lib_module_image" (list . "virtLauncher") }} + domainAttachmentType: tap developerConfiguration: logVerbosity: virtLauncher: {{ $logVerbosity }} From 2d886503d3b8a8ff105207244355499b48a5396a Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 21:15:39 +0300 Subject: [PATCH 08/36] wip Signed-off-by: Dmitry Lopatin --- .../pkg/config/load_network_settings.go | 6 ++++-- .../pkg/controller/kvbuilder/kvvm.go | 6 +++++- .../pkg/controller/vm/internal/service/migration_volumes.go | 4 ++-- .../pkg/controller/vm/internal/sync_kvvm.go | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/images/virtualization-artifact/pkg/config/load_network_settings.go b/images/virtualization-artifact/pkg/config/load_network_settings.go index 1bf35cbd94..a3547b4ac9 100644 --- a/images/virtualization-artifact/pkg/config/load_network_settings.go +++ b/images/virtualization-artifact/pkg/config/load_network_settings.go @@ -18,8 +18,10 @@ package config import "os" -const DisableTapVethBridgeVar = "DISABLE_TAP_VETH_BRIDGE" -const DisableDHCPVar = "DISABLE_DHCP" +const ( + DisableTapVethBridgeVar = "DISABLE_TAP_VETH_BRIDGE" + DisableDHCPVar = "DISABLE_DHCP" +) type NetworkSettings struct { DisableTapVethBridge bool diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go index 95f8e5c2e5..5a2fe6b451 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -797,7 +797,11 @@ func (b *KVVM) SetNetworkInterface(name, macAddress string, acpiIndex int) { Model: devPreset.InterfaceModel, ACPIIndex: acpiIndex, } - iface.Bridge = &virtv1.InterfaceBridge{} + if name == "default" { + iface.Binding = &virtv1.PluginBinding{Name: "bpfbridge"} + } else { + iface.Bridge = &virtv1.InterfaceBridge{} + } if macAddress != "" { iface.MacAddress = macAddress } diff --git a/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go b/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go index f1370e7eb3..555fae6272 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/service/migration_volumes.go @@ -48,14 +48,14 @@ import ( type MigrationVolumesService struct { client client.Client - makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool, disableDHCP bool) (*virtv1.VirtualMachine, error) + makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge, disableDHCP bool) (*virtv1.VirtualMachine, error) delay map[types.UID]time.Time delayDuration time.Duration disableTapVethBridge bool disableDHCP bool } -func NewMigrationVolumesService(client client.Client, makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool, disableDHCP bool) (*virtv1.VirtualMachine, error), delayDuration time.Duration, disableTapVethBridge bool, disableDHCP bool) *MigrationVolumesService { +func NewMigrationVolumesService(client client.Client, makeKVVMFromSpec func(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge, disableDHCP bool) (*virtv1.VirtualMachine, error), delayDuration time.Duration, disableTapVethBridge, disableDHCP bool) *MigrationVolumesService { return &MigrationVolumesService{ client: client, makeKVVMFromSpec: makeKVVMFromSpec, 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 c2cc61804d..6d92576536 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go @@ -454,7 +454,7 @@ func saveKVVMDomainMemoryForPatching(prevKVVM, newKVVM *virtv1.VirtualMachine) * return nil } -func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge bool, disableDHCP bool) (*virtv1.VirtualMachine, error) { +func MakeKVVMFromVMSpec(ctx context.Context, s state.VirtualMachineState, disableTapVethBridge, disableDHCP bool) (*virtv1.VirtualMachine, error) { if s.VirtualMachine().IsEmpty() { return nil, nil } From f0a39626681d226dbf17a881f14347523de047eb Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 21:56:24 +0300 Subject: [PATCH 09/36] wip Signed-off-by: Dmitry Lopatin --- .../virtualization-artifact/pkg/controller/kvbuilder/kvvm.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go index 5a2fe6b451..10c34e9b79 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -28,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/klog/v2" "k8s.io/utils/ptr" virtv1 "kubevirt.io/api/core/v1" @@ -799,8 +800,10 @@ func (b *KVVM) SetNetworkInterface(name, macAddress string, acpiIndex int) { } if name == "default" { iface.Binding = &virtv1.PluginBinding{Name: "bpfbridge"} + klog.Infof("kvbuilder: using bpfbridge binding for default interface %q", name) } else { iface.Bridge = &virtv1.InterfaceBridge{} + klog.Infof("kvbuilder: using bridge binding for non-default interface %q", name) } if macAddress != "" { iface.MacAddress = macAddress From dd9c2ee3a31e259fbf793b85926f99fef172fa91 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 22:08:49 +0300 Subject: [PATCH 10/36] wip Signed-off-by: Dmitry Lopatin --- .../pkg/controller/kvbuilder/kvvm.go | 2 ++ .../pkg/controller/kvbuilder/kvvm_utils.go | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go index 10c34e9b79..4252d43ebf 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -773,8 +773,10 @@ func (b *KVVM) GetOSSettings() map[string]interface{} { } func (b *KVVM) ClearNetworkInterfaces() { + klog.Infof("kvbuilder: ClearNetworkInterfaces before ifaces=%d nets=%d", len(b.Resource.Spec.Template.Spec.Domain.Devices.Interfaces), len(b.Resource.Spec.Template.Spec.Networks)) b.Resource.Spec.Template.Spec.Networks = nil b.Resource.Spec.Template.Spec.Domain.Devices.Interfaces = nil + klog.Infof("kvbuilder: ClearNetworkInterfaces after ifaces=%d nets=%d", len(b.Resource.Spec.Template.Spec.Domain.Devices.Interfaces), len(b.Resource.Spec.Template.Spec.Networks)) } func (b *KVVM) SetNetworkInterface(name, macAddress string, acpiIndex int) { diff --git a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go index df93e6729d..2a58d18cd9 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go @@ -25,6 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/klog/v2" "k8s.io/utils/ptr" virtv1 "kubevirt.io/api/core/v1" @@ -102,6 +103,7 @@ func ApplyVirtualMachineSpec( networkSpec network.InterfaceSpecList, isVmRunning bool, ) error { + klog.Infof("kvbuilder: ApplyVirtualMachineSpec start vm=%s/%s networks=%d existingIfaces=%d", vm.Namespace, vm.Name, len(networkSpec), len(kvvm.Resource.Spec.Template.Spec.Domain.Devices.Interfaces)) if err := kvvm.SetRunPolicy(vm.Spec.RunPolicy); err != nil { return err } @@ -350,10 +352,24 @@ func ApplyMigrationVolumes(kvvm *KVVM, vm *v1alpha2.VirtualMachine, vdsByName ma } func setNetwork(kvvm *KVVM, networkSpec network.InterfaceSpecList) { + klog.Infof("kvbuilder: setNetwork start specLen=%d currentIfaces=%d currentNets=%d", len(networkSpec), len(kvvm.Resource.Spec.Template.Spec.Domain.Devices.Interfaces), len(kvvm.Resource.Spec.Template.Spec.Networks)) + for idx, n := range networkSpec { + klog.Infof("kvbuilder: setNetwork spec[%d] ifName=%q mac=%q id=%d type=%q", idx, n.InterfaceName, n.MAC, n.ID, n.Type) + } kvvm.ClearNetworkInterfaces() + klog.Infof("kvbuilder: after ClearNetworkInterfaces ifaces=%d nets=%d", len(kvvm.Resource.Spec.Template.Spec.Domain.Devices.Interfaces), len(kvvm.Resource.Spec.Template.Spec.Networks)) for _, n := range networkSpec { kvvm.SetNetworkInterface(n.InterfaceName, n.MAC, n.ID) } + klog.Infof("kvbuilder: setNetwork done resultingIfaces=%d resultingNets=%d", len(kvvm.Resource.Spec.Template.Spec.Domain.Devices.Interfaces), len(kvvm.Resource.Spec.Template.Spec.Networks)) + for idx, iface := range kvvm.Resource.Spec.Template.Spec.Domain.Devices.Interfaces { + bindingName := "" + if iface.Binding != nil { + bindingName = iface.Binding.Name + } + isBridge := iface.Bridge != nil + klog.Infof("kvbuilder: resulting iface[%d] name=%q bridge=%t binding=%q", idx, iface.Name, isBridge, bindingName) + } } func setNetworksAnnotation(kvvm *KVVM, networkSpec network.InterfaceSpecList) error { From 9b515cab9cbea2411d746a25f9dbfd41193c18c5 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 23:03:17 +0300 Subject: [PATCH 11/36] wip Signed-off-by: Dmitry Lopatin --- .../virtualization-artifact/pkg/common/network/spec.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/images/virtualization-artifact/pkg/common/network/spec.go b/images/virtualization-artifact/pkg/common/network/spec.go index 4d1976cbc9..c89dd25a1b 100644 --- a/images/virtualization-artifact/pkg/common/network/spec.go +++ b/images/virtualization-artifact/pkg/common/network/spec.go @@ -30,6 +30,16 @@ func CreateNetworkSpec(vm *v1alpha2.VirtualMachine, vmmacs []*v1alpha2.VirtualMa macPool := NewMacAddressPool(vm, vmmacs) var specs InterfaceSpecList + if len(vm.Spec.Networks) == 0 { + return InterfaceSpecList{{ + ID: 1, + Type: v1alpha2.NetworksTypeMain, + Name: "", + InterfaceName: NameDefaultInterface, + MAC: "", + }} + } + for _, net := range vm.Spec.Networks { if net.Type == v1alpha2.NetworksTypeMain { specs = append(specs, createMainInterfaceSpec(net)) From d289ed984d325cd1b293a4df3773c74956657464 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 23:27:55 +0300 Subject: [PATCH 12/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 7 +++++++ images/virt-launcher/werf.inc.yaml | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 89ce7c6935..9c3a29636e 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -115,6 +115,7 @@ shell: - export GOOS=linux - export GOARCH=amd64 - export CGO_ENABLED=0 + - export BPF_CLANG=clang - echo ============== Build container-disk =================== {{- $_ := set $ "ProjectName" (list .ImageName "container-disk" | join "/") }} @@ -213,6 +214,12 @@ shell: - | {{- include "image-build.build" (set $ "BuildCommand" `go build -ldflags="-s -w" -o /kubevirt-binaries/network-bpf-bridge-binding ./cmd/sidecars/network-bpf-bridge-binding/`) | nindent 6 }} + - echo ============== Build bpf_bridge.o ===================== + {{- $_ := set $ "ProjectName" (list $.ImageName "bpf-bridge-obj" | join "/") }} + - mkdir -p /kubevirt-binaries/network-bpf-bridge-binding + - | + {{- include "image-build.build" (set $ "BuildCommand" `clang -O2 -g -target bpf -I/usr/include -c ./cmd/sidecars/network-bpf-bridge-binding/bpf/bpf_bridge.c -o /kubevirt-binaries/network-bpf-bridge-binding/bpf_bridge.o`) | nindent 6 }} + - echo ============== Build virtctl ========================== {{- $_ := set $ "ProjectName" (list .ImageName "virtctl" | join "/") }} - | diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index 106a0116d4..31449be88c 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -202,6 +202,10 @@ import: - virt-launcher-monitor - virt-probe - virt-tail +- image: {{ .ModuleNamePrefix }}virt-artifact + add: /kubevirt-binaries/network-bpf-bridge-binding/bpf_bridge.o + to: /relocate/opt/network-bpf-bridge-binding/bpf_bridge.o + before: setup - image: {{ .ModuleNamePrefix }}virt-artifact add: /kubevirt-binaries to: /relocate/etc/libvirt/hooks/qemu From cf62c946c4ac28021d10f5ee82e2bea2be835a01 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 15:42:57 +0300 Subject: [PATCH 13/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 1 + images/virt-launcher/werf.inc.yaml | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 9c3a29636e..ca91111d23 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -219,6 +219,7 @@ shell: - mkdir -p /kubevirt-binaries/network-bpf-bridge-binding - | {{- include "image-build.build" (set $ "BuildCommand" `clang -O2 -g -target bpf -I/usr/include -c ./cmd/sidecars/network-bpf-bridge-binding/bpf/bpf_bridge.c -o /kubevirt-binaries/network-bpf-bridge-binding/bpf_bridge.o`) | nindent 6 }} + - echo "Built bpf object:" && ls -l /kubevirt-binaries/network-bpf-bridge-binding/ && file /kubevirt-binaries/network-bpf-bridge-binding/bpf_bridge.o || true - echo ============== Build virtctl ========================== {{- $_ := set $ "ProjectName" (list .ImageName "virtctl" | join "/") }} diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index 31449be88c..d6b2925d7b 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -203,9 +203,11 @@ import: - virt-probe - virt-tail - image: {{ .ModuleNamePrefix }}virt-artifact - add: /kubevirt-binaries/network-bpf-bridge-binding/bpf_bridge.o - to: /relocate/opt/network-bpf-bridge-binding/bpf_bridge.o + add: /kubevirt-binaries/network-bpf-bridge-binding/ + to: /relocate/opt/network-bpf-bridge-binding before: setup + includePaths: + - bpf_bridge.o - image: {{ .ModuleNamePrefix }}virt-artifact add: /kubevirt-binaries to: /relocate/etc/libvirt/hooks/qemu From e63c25e745e2b0077f4ba39b60e75fb9f82a2997 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 16:40:22 +0300 Subject: [PATCH 14/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 6 +++--- images/virt-launcher/werf.inc.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index ca91111d23..a63ba77171 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -216,10 +216,10 @@ shell: - echo ============== Build bpf_bridge.o ===================== {{- $_ := set $ "ProjectName" (list $.ImageName "bpf-bridge-obj" | join "/") }} - - mkdir -p /kubevirt-binaries/network-bpf-bridge-binding + - mkdir -p /kubevirt-binaries/network-bpf-bridge-binding-assets - | - {{- include "image-build.build" (set $ "BuildCommand" `clang -O2 -g -target bpf -I/usr/include -c ./cmd/sidecars/network-bpf-bridge-binding/bpf/bpf_bridge.c -o /kubevirt-binaries/network-bpf-bridge-binding/bpf_bridge.o`) | nindent 6 }} - - echo "Built bpf object:" && ls -l /kubevirt-binaries/network-bpf-bridge-binding/ && file /kubevirt-binaries/network-bpf-bridge-binding/bpf_bridge.o || true + {{- include "image-build.build" (set $ "BuildCommand" `clang -O2 -g -target bpf -I/usr/include -c ./cmd/sidecars/network-bpf-bridge-binding/bpf/bpf_bridge.c -o /kubevirt-binaries/network-bpf-bridge-binding-assets/bpf_bridge.o`) | nindent 6 }} + - echo "Built bpf object:" && ls -l /kubevirt-binaries/network-bpf-bridge-binding-assets/ && file /kubevirt-binaries/network-bpf-bridge-binding-assets/bpf_bridge.o || true - echo ============== Build virtctl ========================== {{- $_ := set $ "ProjectName" (list .ImageName "virtctl" | join "/") }} diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index d6b2925d7b..6996b86525 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -203,7 +203,7 @@ import: - virt-probe - virt-tail - image: {{ .ModuleNamePrefix }}virt-artifact - add: /kubevirt-binaries/network-bpf-bridge-binding/ + add: /kubevirt-binaries/network-bpf-bridge-binding-assets/ to: /relocate/opt/network-bpf-bridge-binding before: setup includePaths: From 9b0a3accaf2a657e971614d50efc94981b6311ca Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 16:52:29 +0300 Subject: [PATCH 15/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index a63ba77171..995e4a6d44 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -30,6 +30,7 @@ altPackages: - pkg-config - libtool - gcc-c++ +- clang packages: - libmnl - ncurses From f6d54942621fcbe42947d3b088f1c25e94b5f08c Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 16:58:44 +0300 Subject: [PATCH 16/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 995e4a6d44..efc082488c 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -31,6 +31,7 @@ altPackages: - libtool - gcc-c++ - clang +- libbpf-devel packages: - libmnl - ncurses From 37f9b4ab4b7de0f04d6ca3ee245002acc4d1819d Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 18:25:18 +0300 Subject: [PATCH 17/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index efc082488c..f1b138dd32 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date -- " + echo "$date --- " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From b1c1f4fcafc56c3688abf0cdcb1ab546fc6e715a Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 18:49:28 +0300 Subject: [PATCH 18/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index f1b138dd32..fe0b0b4bc8 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date --- " + echo "$date ---- " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From 5b88ff16bfe4f47649349f4bf8827e4c1bee6eb9 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 19:07:16 +0300 Subject: [PATCH 19/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index fe0b0b4bc8..7ecf4792ac 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date ---- " + echo "$date ----- " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From 883d84c8c3b4586c08dd9ef5c2034041c48ee10d Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 19:27:49 +0300 Subject: [PATCH 20/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-launcher/werf.inc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index 6996b86525..840ccf1852 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -253,6 +253,8 @@ import: after: setup includePaths: - sbin/tc + - lib/tc + - lib64/tc - image: {{ .ModuleNamePrefix }}{{ .ImageName }}-cbuilder add: /bins From 5102a6a437dfbd64a0aa07f44605f17504dc287e Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 20:08:44 +0300 Subject: [PATCH 21/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-launcher/werf.inc.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index 840ccf1852..54eff8d7da 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -401,6 +401,11 @@ shell: echo "Create symlink for run -> var/run " ln -s var/run run + - | + echo "iproute2 runtime contents in /relocate/usr:" + find /relocate/usr \( -path "/relocate/usr/sbin/tc" -o -path "/relocate/usr/lib/tc" -o -path "/relocate/usr/lib/tc/*" -o -path "/relocate/usr/lib64/tc" -o -path "/relocate/usr/lib64/tc/*" \) | sort || true + ls -ld /relocate/usr/lib/tc /relocate/usr/lib64/tc 2>/dev/null || true + # /etc/libvirt-init will be copied back into /etc/libvirt at runtime. This is necessary because we configure libvirt to mount /etc/libvirt and set readOnlyRootFilesystem for other directories. # DO NOT REMOVE. node-labeler.sh uses /etc/libvirt. - | From 1804e1017ee30a5e6efdd606575cab2e45828386 Mon Sep 17 00:00:00 2001 From: Maksim Fedotov Date: Tue, 5 May 2026 10:59:20 +0300 Subject: [PATCH 22/36] add correct paths to tc libs Signed-off-by: Maksim Fedotov --- images/virt-launcher/werf.inc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index 54eff8d7da..a0909cf081 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -253,8 +253,8 @@ import: after: setup includePaths: - sbin/tc - - lib/tc - - lib64/tc + - usr/include + - usr/lib - image: {{ .ModuleNamePrefix }}{{ .ImageName }}-cbuilder add: /bins From 67b078e98232fe16a6cd34e241895754be2dfa4a Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 5 May 2026 23:17:37 +0300 Subject: [PATCH 23/36] wip Signed-off-by: Dmitry Lopatin --- images/packages/iproute2/werf.inc.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 images/packages/iproute2/werf.inc.yaml diff --git a/images/packages/iproute2/werf.inc.yaml b/images/packages/iproute2/werf.inc.yaml new file mode 100644 index 0000000000..2c308fa567 --- /dev/null +++ b/images/packages/iproute2/werf.inc.yaml @@ -0,0 +1,16 @@ +image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }} +final: false +fromImage: builder/scratch +import: +- image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }}-builder + add: /out + to: /{{ .ImageName }} + before: setup + +--- +image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }}-builder +final: false +fromImage: builder/scratch +shell: + install: + - mkdir -p /out From 1d772706624e13925e9761bdf932c7fc441ddbcc Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 5 May 2026 23:22:24 +0300 Subject: [PATCH 24/36] wip Signed-off-by: Dmitry Lopatin --- images/packages/iproute2/werf.inc.yaml | 70 +++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/images/packages/iproute2/werf.inc.yaml b/images/packages/iproute2/werf.inc.yaml index 2c308fa567..cbd80f0468 100644 --- a/images/packages/iproute2/werf.inc.yaml +++ b/images/packages/iproute2/werf.inc.yaml @@ -8,9 +8,75 @@ import: before: setup --- +{{- $version := get .PackageVersion .ImageName }} +{{- $gitRepoUrl := "iproute2/iproute2.git" }} + +image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }}-src-artifact +final: false +fromImage: builder/src +secrets: +- id: SOURCE_REPO + value: {{ .PACKAGE_CLONE_REPO }} +shell: + install: + - git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $version }} /src + +--- +{{- $name := print .ImageName "-dependencies" -}} +{{- define "$name" -}} +altPackages: +- gcc make git autoconf libtool gettext-tools +- automake pkgconf +- flex bison +- elfutils-libelf-devel libbpf-devel +packages: +- glibc +- libcap +- libcap-ng +- libmnl +{{- end -}} + +{{ $builderDependencies := include "$name" . | fromYaml }} + image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }}-builder final: false -fromImage: builder/scratch +fromImage: builder/alt +import: +- image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }}-src-artifact + add: /src + to: /src + before: install +{{- include "importPackageImages" (list . $builderDependencies.packages "install") -}} shell: + beforeInstall: + {{- include "alt packages proxy" . | nindent 2 }} + - | + apt-get install -y \ + {{ $builderDependencies.altPackages | join " " }} + + {{- include "alt packages clean" . | nindent 2 }} + install: - - mkdir -p /out + - | + # Install packages + PKGS="{{ $builderDependencies.packages | join " " }}" + for pkg in $PKGS; do + cp -a /$pkg/. / + rm -rf /$pkg + done + + OUTDIR=/out + + cd /src + + make -j$(nproc) + make DESTDIR=$OUTDIR install + + echo "Built iproute2 contents:" + find $OUTDIR/usr \( -path "$OUTDIR/usr/sbin/tc" -o -path "$OUTDIR/usr/lib/tc" -o -path "$OUTDIR/usr/lib/tc/*" -o -path "$OUTDIR/usr/lib64/tc" -o -path "$OUTDIR/usr/lib64/tc/*" \) | sort || true + + find $OUTDIR -type f -executable | while read -r execfile; do + if strip "$execfile"; then + echo "Stripped: $execfile" + fi + done From 31211ea2eb4ffbde940371402ac1994a488e6215 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 5 May 2026 23:27:42 +0300 Subject: [PATCH 25/36] wip Signed-off-by: Dmitry Lopatin --- images/packages/iproute2/werf.inc.yaml | 82 -------------------------- images/virt-launcher/werf.inc.yaml | 13 ++++ 2 files changed, 13 insertions(+), 82 deletions(-) delete mode 100644 images/packages/iproute2/werf.inc.yaml diff --git a/images/packages/iproute2/werf.inc.yaml b/images/packages/iproute2/werf.inc.yaml deleted file mode 100644 index cbd80f0468..0000000000 --- a/images/packages/iproute2/werf.inc.yaml +++ /dev/null @@ -1,82 +0,0 @@ -image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }} -final: false -fromImage: builder/scratch -import: -- image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }}-builder - add: /out - to: /{{ .ImageName }} - before: setup - ---- -{{- $version := get .PackageVersion .ImageName }} -{{- $gitRepoUrl := "iproute2/iproute2.git" }} - -image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }}-src-artifact -final: false -fromImage: builder/src -secrets: -- id: SOURCE_REPO - value: {{ .PACKAGE_CLONE_REPO }} -shell: - install: - - git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $version }} /src - ---- -{{- $name := print .ImageName "-dependencies" -}} -{{- define "$name" -}} -altPackages: -- gcc make git autoconf libtool gettext-tools -- automake pkgconf -- flex bison -- elfutils-libelf-devel libbpf-devel -packages: -- glibc -- libcap -- libcap-ng -- libmnl -{{- end -}} - -{{ $builderDependencies := include "$name" . | fromYaml }} - -image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }}-builder -final: false -fromImage: builder/alt -import: -- image: {{ .ModuleNamePrefix }}{{ .PackagePath }}/{{ .ImageName }}-src-artifact - add: /src - to: /src - before: install -{{- include "importPackageImages" (list . $builderDependencies.packages "install") -}} -shell: - beforeInstall: - {{- include "alt packages proxy" . | nindent 2 }} - - | - apt-get install -y \ - {{ $builderDependencies.altPackages | join " " }} - - {{- include "alt packages clean" . | nindent 2 }} - - install: - - | - # Install packages - PKGS="{{ $builderDependencies.packages | join " " }}" - for pkg in $PKGS; do - cp -a /$pkg/. / - rm -rf /$pkg - done - - OUTDIR=/out - - cd /src - - make -j$(nproc) - make DESTDIR=$OUTDIR install - - echo "Built iproute2 contents:" - find $OUTDIR/usr \( -path "$OUTDIR/usr/sbin/tc" -o -path "$OUTDIR/usr/lib/tc" -o -path "$OUTDIR/usr/lib/tc/*" -o -path "$OUTDIR/usr/lib64/tc" -o -path "$OUTDIR/usr/lib64/tc/*" \) | sort || true - - find $OUTDIR -type f -executable | while read -r execfile; do - if strip "$execfile"; then - echo "Stripped: $execfile" - fi - done diff --git a/images/virt-launcher/werf.inc.yaml b/images/virt-launcher/werf.inc.yaml index a0909cf081..bd5afce159 100644 --- a/images/virt-launcher/werf.inc.yaml +++ b/images/virt-launcher/werf.inc.yaml @@ -77,6 +77,7 @@ altLibs: - psmisc - msulogin - strace + - iproute2 binaries: # GNU utils (required to run swtpm). - /usr/bin/certtool @@ -401,6 +402,18 @@ shell: echo "Create symlink for run -> var/run " ln -s var/run run + echo "Copy system tc and runtime dirs" + mkdir -p /relocate/usr/sbin + cp -a /usr/sbin/tc /relocate/usr/sbin/tc + if [ -d /usr/lib/tc ]; then + mkdir -p /relocate/usr/lib + cp -a /usr/lib/tc /relocate/usr/lib/tc + fi + if [ -d /usr/lib64/tc ]; then + mkdir -p /relocate/usr/lib64 + cp -a /usr/lib64/tc /relocate/usr/lib64/tc + fi + - | echo "iproute2 runtime contents in /relocate/usr:" find /relocate/usr \( -path "/relocate/usr/sbin/tc" -o -path "/relocate/usr/lib/tc" -o -path "/relocate/usr/lib/tc/*" -o -path "/relocate/usr/lib64/tc" -o -path "/relocate/usr/lib64/tc/*" \) | sort || true From ec901dfa501f51e08aa2b1645b3e9e6c8eaea9b2 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 5 May 2026 23:52:05 +0300 Subject: [PATCH 26/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 7ecf4792ac..c58bfd2b5d 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date ----- " + echo "$date ------ " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From cd213e192f013b34352b14a685cc708bc8e77988 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 6 May 2026 20:10:23 +0300 Subject: [PATCH 27/36] wip Signed-off-by: Dmitry Lopatin --- templates/kubevirt/kubevirt.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/kubevirt/kubevirt.yaml b/templates/kubevirt/kubevirt.yaml index a869cac786..35b9bbf7b4 100644 --- a/templates/kubevirt/kubevirt.yaml +++ b/templates/kubevirt/kubevirt.yaml @@ -43,7 +43,6 @@ spec: binding: bpfbridge: sidecarImage: {{ include "helm_lib_module_image" (list . "virtLauncher") }} - domainAttachmentType: tap developerConfiguration: logVerbosity: virtLauncher: {{ $logVerbosity }} From 8e73c1610d0c93a1377999305e5925e1192f8929 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 6 May 2026 21:48:36 +0300 Subject: [PATCH 28/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index c58bfd2b5d..686a306528 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date ------ " + echo "$date ------- " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From 05a99c134b5a47c13f7d680e4dfa7941f86b5e2c Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 6 May 2026 22:28:42 +0300 Subject: [PATCH 29/36] wip Signed-off-by: Dmitry Lopatin --- templates/kubevirt/kubevirt.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/kubevirt/kubevirt.yaml b/templates/kubevirt/kubevirt.yaml index 35b9bbf7b4..d6d8fe9ba0 100644 --- a/templates/kubevirt/kubevirt.yaml +++ b/templates/kubevirt/kubevirt.yaml @@ -43,6 +43,7 @@ spec: binding: bpfbridge: sidecarImage: {{ include "helm_lib_module_image" (list . "virtLauncher") }} + migration: {} developerConfiguration: logVerbosity: virtLauncher: {{ $logVerbosity }} From c45e7e97ed755a578e9d6f3292b30b853aed0fac Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 11 May 2026 20:37:51 +0300 Subject: [PATCH 30/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 686a306528..f021137f1f 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date ------- " + echo "$date -------- " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From 4570c3c623a782b442a9089749f7a0a59eb8d7a8 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 12 May 2026 17:21:22 +0300 Subject: [PATCH 31/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index f021137f1f..77ffff8a30 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date -------- " + echo "$date --------- " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From 76aef0eb4f6d9eca4f1aa4c8c52beb113e932642 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 13 May 2026 22:30:54 +0300 Subject: [PATCH 32/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index 77ffff8a30..f3117029a7 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date --------- " + echo "$date --------- new --- " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From 14c68d7cf1e9e61b95c0a5642c12ee38f2fe04e2 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Thu, 14 May 2026 19:37:33 +0300 Subject: [PATCH 33/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index f3117029a7..d1d746127e 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -16,7 +16,7 @@ shell: installCacheVersion: "{{ now | date "Mon Jan 2 15:04:05 MST 2006" }}" install: - | - echo "$date --------- new --- " + echo "$date --------- new ---- " echo "Git clone {{ $gitRepoName }} repository..." git clone --depth=1 $(cat /run/secrets/SOURCE_REPO)/{{ $gitRepoUrl }} --branch {{ $tag }} /src/kubevirt From c50d83ff8fcd890ff94cbe2efb482a4dec0c8cad Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 19 May 2026 23:42:48 +0300 Subject: [PATCH 34/36] wip Signed-off-by: Dmitry Lopatin --- .../cmd/virtualization-controller/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/virtualization-artifact/cmd/virtualization-controller/main.go b/images/virtualization-artifact/cmd/virtualization-controller/main.go index 453148ce87..a512ab3955 100644 --- a/images/virtualization-artifact/cmd/virtualization-controller/main.go +++ b/images/virtualization-artifact/cmd/virtualization-controller/main.go @@ -362,7 +362,7 @@ func main() { } vmLogger := logger.NewControllerLogger(vm.ControllerName, logLevel, logOutput, logDebugVerbosity, logDebugControllerList) - if err = vm.SetupController(ctx, mgr, virtClient, vmLogger, dvcrSettings, firmwareImage, controllerNamespace, networkSettings.DisableTapVethBridge); err != nil { + if err = vm.SetupController(ctx, mgr, virtClient, vmLogger, dvcrSettings, firmwareImage, controllerNamespace, networkSettings.DisableTapVethBridge, networkSettings.DisableDHCP); err != nil { log.Error(err.Error()) os.Exit(1) } From 56758faa292405058c9f530753f6b1b531272f2c Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 19 May 2026 23:55:19 +0300 Subject: [PATCH 35/36] wip Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index d1d746127e..d0ee12e7d6 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -211,16 +211,11 @@ shell: - | {{- include "image-build.build" (set $ "BuildCommand" `go build -ldflags="-s -w" -o /kubevirt-binaries/sidecars ./cmd/sidecars/`) | nindent 6 }} - - echo ============== Build network-bpf-bridge-binding ======= - {{- $_ := set $ "ProjectName" (list $.ImageName "network-bpf-bridge-binding" | join "/") }} - - | - {{- include "image-build.build" (set $ "BuildCommand" `go build -ldflags="-s -w" -o /kubevirt-binaries/network-bpf-bridge-binding ./cmd/sidecars/network-bpf-bridge-binding/`) | nindent 6 }} - - echo ============== Build bpf_bridge.o ===================== {{- $_ := set $ "ProjectName" (list $.ImageName "bpf-bridge-obj" | join "/") }} - mkdir -p /kubevirt-binaries/network-bpf-bridge-binding-assets - | - {{- include "image-build.build" (set $ "BuildCommand" `clang -O2 -g -target bpf -I/usr/include -c ./cmd/sidecars/network-bpf-bridge-binding/bpf/bpf_bridge.c -o /kubevirt-binaries/network-bpf-bridge-binding-assets/bpf_bridge.o`) | nindent 6 }} + {{- include "image-build.build" (set $ "BuildCommand" `clang -O2 -g -target bpf -I/usr/include -c ./pkg/network/bpfbridge/bpf/bpf_bridge.c -o /kubevirt-binaries/network-bpf-bridge-binding-assets/bpf_bridge.o`) | nindent 6 }} - echo "Built bpf object:" && ls -l /kubevirt-binaries/network-bpf-bridge-binding-assets/ && file /kubevirt-binaries/network-bpf-bridge-binding-assets/bpf_bridge.o || true - echo ============== Build virtctl ========================== From f73c46f1ee45090b35c7604168ca3f5761a15f86 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 20 May 2026 19:29:27 +0300 Subject: [PATCH 36/36] wip Signed-off-by: Dmitry Lopatin --- templates/kubevirt/kubevirt.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/kubevirt/kubevirt.yaml b/templates/kubevirt/kubevirt.yaml index d6d8fe9ba0..efa8753b4f 100644 --- a/templates/kubevirt/kubevirt.yaml +++ b/templates/kubevirt/kubevirt.yaml @@ -42,7 +42,7 @@ spec: network: binding: bpfbridge: - sidecarImage: {{ include "helm_lib_module_image" (list . "virtLauncher") }} + domainAttachmentType: tap migration: {} developerConfiguration: logVerbosity: