From a84dd3476c7aba97205ee7763281a7e3bd79a27e Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 14 Apr 2026 15:23:15 +0300 Subject: [PATCH 01/30] 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 | 5 +-- openapi/config-values.yaml | 13 ++++++++ .../virtualization-controller/_helpers.tpl | 2 ++ 12 files changed, 95 insertions(+), 28 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 75669f228b..8ae3218ef3 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); err != nil { + if err = vm.SetupController(ctx, mgr, virtClient, vmLogger, dvcrSettings, firmwareImage, 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 6eeddc1ad9..c85c0143a4 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -67,6 +67,7 @@ const ( type KVVMOptions struct { EnableParavirtualization bool OsType v1alpha2.OsType + DisableTapVethBridge bool // These options are for local development mode DisableHypervSyNIC bool @@ -92,6 +93,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 61edd64c33..2771238341 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go @@ -111,6 +111,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 2fc332e9ae..71fe47854e 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, } } @@ -476,7 +478,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 dbbd4db4be..f61f95c6fd 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) { @@ -349,7 +352,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) } @@ -378,7 +381,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) } @@ -444,7 +447,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 } @@ -452,6 +455,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 21b3ba6100..44f9fd8b11 100644 --- a/images/virtualization-artifact/pkg/controller/vm/vm_controller.go +++ b/images/virtualization-artifact/pkg/controller/vm/vm_controller.go @@ -51,6 +51,7 @@ func SetupController( log *log.Logger, dvcrSettings *dvcr.Settings, firmwareImage string, + disableTapVethBridge bool, ) error { recorder := eventrecord.NewEventRecorderLogger(mgr, ControllerName) mgrCache := mgr.GetCache() @@ -58,7 +59,7 @@ func SetupController( blockDeviceService := service.NewBlockDeviceService(client) vmClassService := service.NewVirtualMachineClassService(client) - migrateVolumesService := vmservice.NewMigrationVolumesService(client, internal.MakeKVVMFromVMSpec, 10*time.Second) + migrateVolumesService := vmservice.NewMigrationVolumesService(client, internal.MakeKVVMFromVMSpec, 10*time.Second, disableTapVethBridge) handlers := []Handler{ internal.NewMaintenanceHandler(client), @@ -76,7 +77,7 @@ func SetupController( internal.NewPodHandler(client), internal.NewSizePolicyHandler(), internal.NewNetworkInterfaceHandler(featuregates.Default()), - internal.NewSyncKvvmHandler(dvcrSettings, client, recorder, featuregates.Default(), migrateVolumesService), + 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 bc57f9f10c2ba90d172ca1638833286eb3ae0f7e Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 6 May 2026 20:17:40 +0300 Subject: [PATCH 02/30] 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 daf7a6a989..d25bd9b984 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.28 + 3p-kubevirt: feat/vm/disable-tap-veth-bridge 3p-containerized-data-importer: v1.60.3-v12n.18 distribution: 2.8.3 package: From 90e5514d7196a31258301a47f9b6656788477d35 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Thu, 16 Apr 2026 22:30:14 +0300 Subject: [PATCH 03/30] feat(vm): add disable DHCP VM setting Signed-off-by: Dmitry Lopatin --- images/virt-artifact/werf.inc.yaml | 2 ++ .../cmd/virtualization-controller/main.go | 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 ++ 13 files changed, 41 insertions(+), 11 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/cmd/virtualization-controller/main.go b/images/virtualization-artifact/cmd/virtualization-controller/main.go index 8ae3218ef3..f1db0e7b9a 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, networkSettings.DisableTapVethBridge); err != nil { + if err = vm.SetupController(ctx, mgr, virtClient, vmLogger, dvcrSettings, firmwareImage, networkSettings.DisableTapVethBridge, networkSettings.DisableDHCP); 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 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 c85c0143a4..563fc422f8 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -68,6 +68,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 2771238341..20bac3ee64 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go @@ -116,6 +116,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 71fe47854e..1a73a395de 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, } } @@ -478,7 +480,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 f61f95c6fd..0e3277f507 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) { @@ -352,7 +355,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) } @@ -381,7 +384,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) } @@ -447,7 +450,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 } @@ -456,6 +459,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 44f9fd8b11..3ff7b81cb0 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, disableTapVethBridge bool, + disableDHCP bool, ) error { recorder := eventrecord.NewEventRecorderLogger(mgr, ControllerName) mgrCache := mgr.GetCache() @@ -59,7 +60,7 @@ func SetupController( blockDeviceService := service.NewBlockDeviceService(client) vmClassService := service.NewVirtualMachineClassService(client) - 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), @@ -77,7 +78,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 00c6fdb7b885076ed3894f9f1ac030e55818634a Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 28 Apr 2026 23:56:56 +0300 Subject: [PATCH 04/30] 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 9c9c2c2c112ec00ffa6196cfe079e23b9615978f Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 15:00:43 +0300 Subject: [PATCH 05/30] 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 959fec9b434a31646a731a7126413ef4c7958893 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 20:15:05 +0300 Subject: [PATCH 06/30] 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 e1726c0d9a81a0be3898186c3aec8729e763c2b5 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 20:49:25 +0300 Subject: [PATCH 07/30] 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 19463005e009766e0220662dd71ef2639c1cb6c5 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 21:15:39 +0300 Subject: [PATCH 08/30] 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 563fc422f8..9df27c497d 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -771,7 +771,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 1a73a395de..51c0126ab8 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 0e3277f507..fb0669679c 100644 --- a/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go +++ b/images/virtualization-artifact/pkg/controller/vm/internal/sync_kvvm.go @@ -450,7 +450,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 bdcffad3633c7693a6e9741cc38d79beac60f316 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 21:56:24 +0300 Subject: [PATCH 09/30] 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 9df27c497d..d0380ed8e9 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" @@ -773,8 +774,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 b2aa1ccda19ba9d0c459c00bbd680f5c3e7f544f Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 22:08:49 +0300 Subject: [PATCH 10/30] 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 d0380ed8e9..fc21abc3ea 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm.go @@ -747,8 +747,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 20bac3ee64..2124f815a7 100644 --- a/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go +++ b/images/virtualization-artifact/pkg/controller/kvbuilder/kvvm_utils.go @@ -24,6 +24,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" "sigs.k8s.io/controller-runtime/pkg/client" @@ -96,6 +97,7 @@ func ApplyVirtualMachineSpec( ipAddress string, networkSpec network.InterfaceSpecList, ) 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 } @@ -365,10 +367,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 8d221f2549e8092d276b601fb0cc2f8b34729d35 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 23:03:17 +0300 Subject: [PATCH 11/30] 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 9ed90aad86fc85d7742402a3206dc8b9086c69d8 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Sun, 3 May 2026 23:27:55 +0300 Subject: [PATCH 12/30] 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 794b8d0d071229901eae43a4cbe9e04e7aca9ed3 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 15:42:57 +0300 Subject: [PATCH 13/30] 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 474f08453ac8ac6a89df0e841d1b826d537c5574 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 16:40:22 +0300 Subject: [PATCH 14/30] 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 372f95ab851fa2340a28dd4b23353697030f0452 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 16:52:29 +0300 Subject: [PATCH 15/30] 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 9bd142e1cd6bbbd40d3fa870ab796cd21d4d64dc Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 16:58:44 +0300 Subject: [PATCH 16/30] 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 282e0f2718b258595c2183b5264887a8e8fc7a43 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 18:25:18 +0300 Subject: [PATCH 17/30] 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 df8dd97cc08b9a9f5df26e270ae5865dffc23ed2 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 18:49:28 +0300 Subject: [PATCH 18/30] 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 0a26b55c328e53d7ef5761bc34db799e9d610aa8 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 19:07:16 +0300 Subject: [PATCH 19/30] 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 8d83c8f2c0491d75667fb444f2be1d22581fcaca Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 19:27:49 +0300 Subject: [PATCH 20/30] 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 4368662d95768c4c7c74fe89dca531b7c06dc03b Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 4 May 2026 20:08:44 +0300 Subject: [PATCH 21/30] 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 dc500aef9cb8ffd0bbe95722a7ce483e1d0692c1 Mon Sep 17 00:00:00 2001 From: Maksim Fedotov Date: Tue, 5 May 2026 10:59:20 +0300 Subject: [PATCH 22/30] 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 906eb88889a156381df3174b419938f64a1b972e Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 5 May 2026 23:17:37 +0300 Subject: [PATCH 23/30] 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 5ed7e4e2c3c54dece4e8cd9637a5a6570d0c9108 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 5 May 2026 23:22:24 +0300 Subject: [PATCH 24/30] 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 b772a4d570583d273e5bdcf825acef49b3c23e0e Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 5 May 2026 23:27:42 +0300 Subject: [PATCH 25/30] 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 a8eeaccf1af68bf13682804cb98bd600ea63ebe5 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Tue, 5 May 2026 23:52:05 +0300 Subject: [PATCH 26/30] 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 59cf07c75c5cfb017d05adb49a4ee98c723b9b87 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 6 May 2026 20:10:23 +0300 Subject: [PATCH 27/30] 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 6f8a5fb9da41b8607f64f819e7d70460c5a2eb41 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 6 May 2026 21:48:36 +0300 Subject: [PATCH 28/30] 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 4b8765eb2fad4d0b11f6a8c6f04a9da6058e2b2a Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Wed, 6 May 2026 22:28:42 +0300 Subject: [PATCH 29/30] 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 2b6ee8c5626c82c1206938b5a7976c3236a09561 Mon Sep 17 00:00:00 2001 From: Dmitry Lopatin Date: Mon, 11 May 2026 20:37:51 +0300 Subject: [PATCH 30/30] 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