diff --git a/api/core/v1alpha2/vmopcondition/condition.go b/api/core/v1alpha2/vmopcondition/condition.go index 9326c306ec..f025b424ca 100644 --- a/api/core/v1alpha2/vmopcondition/condition.go +++ b/api/core/v1alpha2/vmopcondition/condition.go @@ -101,6 +101,10 @@ const ( // ReasonTargetPreparing indicates that target pod is being prepared. ReasonTargetPreparing ReasonCompleted = "TargetPreparing" + // ReasonWaitingForSyncSlot indicates that the target pod is prepared but the + // migration is waiting for a free data-transfer (sync) slot on the source node. + ReasonWaitingForSyncSlot ReasonCompleted = "WaitingForSyncSlot" + // ReasonSyncing indicates that source and target are synchronizing migration data. ReasonSyncing ReasonCompleted = "Syncing" diff --git a/build/components/versions.yml b/build/components/versions.yml index 02d20930a8..72bbacd982 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.24 + 3p-kubevirt: feat/core/two-pool-migration 3p-containerized-data-importer: v1.60.3-v12n.18 distribution: 2.8.3 package: diff --git a/crds/embedded/kubevirt.yaml b/crds/embedded/kubevirt.yaml index 3ba8b7b991..11e71e1460 100644 --- a/crds/embedded/kubevirt.yaml +++ b/crds/embedded/kubevirt.yaml @@ -636,6 +636,14 @@ spec: allowed per node. Defaults to 2 format: int32 type: integer + parallelSyncMigrationsPerNode: + description: |- + ParallelSyncMigrationsPerNode is the maximum number of concurrent outgoing live migrations + per source node allowed to be in the data-transfer (sync) phase. Migrations above this cap + wait in PreparingTarget with a WaitingForSyncSlot condition until a slot frees. + Effective value is clamped to ParallelOutboundMigrationsPerNode. Defaults to 1. + format: int32 + type: integer progressTimeout: description: |- ProgressTimeout is the maximum number of seconds a live migration is allowed to make no progress. diff --git a/images/hooks/pkg/hooks/migration-config/hook.go b/images/hooks/pkg/hooks/migration-config/hook.go index 7edf9b861a..2cdb7df796 100644 --- a/images/hooks/pkg/hooks/migration-config/hook.go +++ b/images/hooks/pkg/hooks/migration-config/hook.go @@ -36,18 +36,21 @@ const ( bandwidthPerMigrationAnnotation = "virtualization.deckhouse.io/bandwidth-per-migration" completionTimeoutPerGiBAnnotation = "virtualization.deckhouse.io/completion-timeout-per-gib" parallelOutboundMigrationsPerNodeAnnotation = "virtualization.deckhouse.io/parallel-outbound-migrations-per-node" + parallelSyncMigrationsPerNodeAnnotation = "virtualization.deckhouse.io/parallel-sync-migrations-per-node" progressTimeoutAnnotation = "virtualization.deckhouse.io/progress-timeout" disableTLSAnnotation = "virtualization.deckhouse.io/disable-tls" bandwidthPerMigrationValuesPath = "virtualization.internal.virtConfig.bandwidthPerMigration" completionTimeoutPerGiBValuesPath = "virtualization.internal.virtConfig.completionTimeoutPerGiB" parallelOutboundMigrationsPerNodeValuesPath = "virtualization.internal.virtConfig.parallelOutboundMigrationsPerNode" + parallelSyncMigrationsPerNodeValuesPath = "virtualization.internal.virtConfig.parallelSyncMigrationsPerNode" progressTimeoutValuesPath = "virtualization.internal.virtConfig.progressTimeout" disableTLSValuesPath = "virtualization.internal.virtConfig.disableTLS" defaultBandwidthPerMigration = "640Mi" defaultCompletionTimeoutPerGiB = 800 - defaultParallelOutboundMigrationsPerNode = 1 + defaultParallelOutboundMigrationsPerNode = 2 + defaultParallelSyncMigrationsPerNode = 1 defaultProgressTimeout = 150 defaultDisableTLS = false ) @@ -71,6 +74,11 @@ var migrationParams = []migrationParam{ valuesPath: parallelOutboundMigrationsPerNodeValuesPath, defaultValue: defaultParallelOutboundMigrationsPerNode, }, + { + annotation: parallelSyncMigrationsPerNodeAnnotation, + valuesPath: parallelSyncMigrationsPerNodeValuesPath, + defaultValue: defaultParallelSyncMigrationsPerNode, + }, { annotation: progressTimeoutAnnotation, valuesPath: progressTimeoutValuesPath, diff --git a/images/hooks/pkg/hooks/migration-config/hook_test.go b/images/hooks/pkg/hooks/migration-config/hook_test.go index b5e1aae968..bed655a081 100644 --- a/images/hooks/pkg/hooks/migration-config/hook_test.go +++ b/images/hooks/pkg/hooks/migration-config/hook_test.go @@ -83,6 +83,7 @@ var _ = Describe("MigrationConfig", func() { bandwidthPerMigrationAnnotation: "1Gi", completionTimeoutPerGiBAnnotation: "1200", parallelOutboundMigrationsPerNodeAnnotation: "5", + parallelSyncMigrationsPerNodeAnnotation: "3", progressTimeoutAnnotation: "300", disableTLSAnnotation: "true", })) @@ -95,6 +96,8 @@ var _ = Describe("MigrationConfig", func() { return gjson.Result{Type: gjson.Number, Num: defaultCompletionTimeoutPerGiB} case parallelOutboundMigrationsPerNodeValuesPath: return gjson.Result{Type: gjson.Number, Num: defaultParallelOutboundMigrationsPerNode} + case parallelSyncMigrationsPerNodeValuesPath: + return gjson.Result{Type: gjson.Number, Num: defaultParallelSyncMigrationsPerNode} case progressTimeoutValuesPath: return gjson.Result{Type: gjson.Number, Num: defaultProgressTimeout} case disableTLSValuesPath: @@ -113,6 +116,7 @@ var _ = Describe("MigrationConfig", func() { Expect(setValues).To(HaveKeyWithValue(bandwidthPerMigrationValuesPath, "1Gi")) Expect(setValues).To(HaveKeyWithValue(completionTimeoutPerGiBValuesPath, 1200)) Expect(setValues).To(HaveKeyWithValue(parallelOutboundMigrationsPerNodeValuesPath, 5)) + Expect(setValues).To(HaveKeyWithValue(parallelSyncMigrationsPerNodeValuesPath, 3)) Expect(setValues).To(HaveKeyWithValue(progressTimeoutValuesPath, 300)) Expect(setValues).To(HaveKeyWithValue(disableTLSValuesPath, true)) }) @@ -128,6 +132,8 @@ var _ = Describe("MigrationConfig", func() { return gjson.Result{Type: gjson.Number, Num: 9999} case parallelOutboundMigrationsPerNodeValuesPath: return gjson.Result{Type: gjson.Number, Num: 9999} + case parallelSyncMigrationsPerNodeValuesPath: + return gjson.Result{Type: gjson.Number, Num: 9999} case progressTimeoutValuesPath: return gjson.Result{Type: gjson.Number, Num: 9999} case disableTLSValuesPath: @@ -146,6 +152,7 @@ var _ = Describe("MigrationConfig", func() { Expect(setValues).To(HaveKeyWithValue(bandwidthPerMigrationValuesPath, defaultBandwidthPerMigration)) Expect(setValues).To(HaveKeyWithValue(completionTimeoutPerGiBValuesPath, defaultCompletionTimeoutPerGiB)) Expect(setValues).To(HaveKeyWithValue(parallelOutboundMigrationsPerNodeValuesPath, defaultParallelOutboundMigrationsPerNode)) + Expect(setValues).To(HaveKeyWithValue(parallelSyncMigrationsPerNodeValuesPath, defaultParallelSyncMigrationsPerNode)) Expect(setValues).To(HaveKeyWithValue(progressTimeoutValuesPath, defaultProgressTimeout)) Expect(setValues).To(HaveKeyWithValue(disableTLSValuesPath, defaultDisableTLS)) }) @@ -154,7 +161,8 @@ var _ = Describe("MigrationConfig", func() { setSnapshots(newSnapshot(map[string]string{ bandwidthPerMigrationAnnotation: defaultBandwidthPerMigration, completionTimeoutPerGiBAnnotation: "800", - parallelOutboundMigrationsPerNodeAnnotation: "1", + parallelOutboundMigrationsPerNodeAnnotation: "2", + parallelSyncMigrationsPerNodeAnnotation: "1", progressTimeoutAnnotation: "150", disableTLSAnnotation: "false", })) @@ -167,6 +175,8 @@ var _ = Describe("MigrationConfig", func() { return gjson.Result{Type: gjson.Number, Num: defaultCompletionTimeoutPerGiB} case parallelOutboundMigrationsPerNodeValuesPath: return gjson.Result{Type: gjson.Number, Num: defaultParallelOutboundMigrationsPerNode} + case parallelSyncMigrationsPerNodeValuesPath: + return gjson.Result{Type: gjson.Number, Num: defaultParallelSyncMigrationsPerNode} case progressTimeoutValuesPath: return gjson.Result{Type: gjson.Number, Num: defaultProgressTimeout} case disableTLSValuesPath: @@ -214,6 +224,8 @@ var _ = Describe("MigrationConfig", func() { return gjson.Result{Type: gjson.Number, Num: defaultCompletionTimeoutPerGiB} case parallelOutboundMigrationsPerNodeValuesPath: return gjson.Result{Type: gjson.Number, Num: defaultParallelOutboundMigrationsPerNode} + case parallelSyncMigrationsPerNodeValuesPath: + return gjson.Result{Type: gjson.Number, Num: defaultParallelSyncMigrationsPerNode} case progressTimeoutValuesPath: return gjson.Result{Type: gjson.Number, Num: defaultProgressTimeout} case disableTLSValuesPath: @@ -243,6 +255,8 @@ var _ = Describe("MigrationConfig", func() { return gjson.Result{Type: gjson.Number, Num: defaultCompletionTimeoutPerGiB} case parallelOutboundMigrationsPerNodeValuesPath: return gjson.Result{Type: gjson.Number, Num: defaultParallelOutboundMigrationsPerNode} + case parallelSyncMigrationsPerNodeValuesPath: + return gjson.Result{Type: gjson.Number, Num: defaultParallelSyncMigrationsPerNode} case progressTimeoutValuesPath: return gjson.Result{Type: gjson.Number, Num: defaultProgressTimeout} case disableTLSValuesPath: diff --git a/images/virt-artifact/werf.inc.yaml b/images/virt-artifact/werf.inc.yaml index f30560fba6..9c6ad562d5 100644 --- a/images/virt-artifact/werf.inc.yaml +++ b/images/virt-artifact/werf.inc.yaml @@ -9,6 +9,7 @@ image: {{ .ModuleNamePrefix }}{{ .ImageName }}-src-artifact final: false fromImage: builder/src +fromCacheVersion: "two-pool-migration-1" secrets: - id: SOURCE_REPO value: {{ $.SOURCE_REPO }} @@ -44,6 +45,7 @@ packages: image: {{ .ModuleNamePrefix }}{{ .ImageName }} final: false fromImage: {{ eq $.SVACE_ENABLED "false" | ternary "builder/golang-alt-1.25" "builder/golang-alt-svace-1.25" }} +fromCacheVersion: "two-pool-migration-1" mount: - fromPath: ~/go-pkg-cache to: /go/pkg diff --git a/images/virt-controller/werf.inc.yaml b/images/virt-controller/werf.inc.yaml index c1f7113305..ed8da6cfa1 100644 --- a/images/virt-controller/werf.inc.yaml +++ b/images/virt-controller/werf.inc.yaml @@ -1,6 +1,7 @@ --- image: {{ .ModuleNamePrefix }}{{ .ImageName }} fromImage: {{ .ModuleNamePrefix }}distroless +fromCacheVersion: "two-pool-migration-1" git: {{- include "image mount points" . }} import: diff --git a/images/virt-operator/werf.inc.yaml b/images/virt-operator/werf.inc.yaml index dda81277a1..5ab966a3f6 100644 --- a/images/virt-operator/werf.inc.yaml +++ b/images/virt-operator/werf.inc.yaml @@ -1,6 +1,7 @@ --- image: {{ .ModuleNamePrefix }}{{ .ImageName }} fromImage: {{ .ModuleNamePrefix }}distroless +fromCacheVersion: "two-pool-migration-1" git: {{- include "image mount points" . }} import: diff --git a/images/virtualization-artifact/go.mod b/images/virtualization-artifact/go.mod index 32e1b85473..41e2750e3f 100644 --- a/images/virtualization-artifact/go.mod +++ b/images/virtualization-artifact/go.mod @@ -168,4 +168,4 @@ replace ( ) // Kubevirt API replaces -replace kubevirt.io/api => github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v0.0.0-20260403154920-301347b413ce +replace kubevirt.io/api => github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v0.0.0-20260417064344-ebd8172aaa7b diff --git a/images/virtualization-artifact/go.sum b/images/virtualization-artifact/go.sum index 2d94d61e2c..82204e8f84 100644 --- a/images/virtualization-artifact/go.sum +++ b/images/virtualization-artifact/go.sum @@ -51,6 +51,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v0.0.0-20260403154920-301347b413ce h1:b6I/SUcA30j2wcOBBERbN20cKARaDAHNtSzP4XB6kgg= github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v0.0.0-20260403154920-301347b413ce/go.mod h1:wGZLfRa/b4w/V/hakmfcK0CmrAZGfpj+jN7BMt0s19E= +github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v0.0.0-20260417064344-ebd8172aaa7b h1:MnsWSUYWW/xMg9b2gU5Oqi72DTG1eYSQHpioPNFW/zQ= +github.com/deckhouse/3p-kubevirt/staging/src/kubevirt.io/api v0.0.0-20260417064344-ebd8172aaa7b/go.mod h1:wGZLfRa/b4w/V/hakmfcK0CmrAZGfpj+jN7BMt0s19E= github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250226105106-176cd3afcdd5 h1:PsN1E0oxC/+4zdA977txrqUCuObFL3HAuu5Xnud8m8c= github.com/deckhouse/deckhouse/pkg/log v0.0.0-20250226105106-176cd3afcdd5/go.mod h1:Mk5HRzkc5pIcDIZ2JJ6DPuuqnwhXVkb3you8M8Mg+4w= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= diff --git a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go index 9bac41519f..cf41dc385e 100644 --- a/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go +++ b/images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go @@ -50,6 +50,7 @@ const ( progressDisksPreparing int32 = 1 progressTargetScheduling int32 = 2 progressTargetPreparing int32 = 3 + progressWaitingForSyncSlot int32 = 4 progressSourceSuspended int32 = 91 progressTargetResumed int32 = 92 progressMigrationCompleted int32 = 100 @@ -59,6 +60,7 @@ const ( messageSyncingSourceAndTarget = "Syncing source and target" messageTargetPodScheduling = "Target pod is being scheduled" messageTargetPodPreparing = "Target pod is being prepared" + messageWaitingForSyncSlot = "Target prepared; waiting for sync slot on source node" messageTargetVMResumed = "Target VM resumed" messageSourceVMSuspended = "Source VM suspended" ) @@ -579,6 +581,13 @@ func (h LifecycleHandler) getInProgressReasonAndMessage( case virtv1.MigrationScheduled, virtv1.MigrationPreparingTarget: reason = vmopcondition.ReasonTargetPreparing message = messageTargetPodPreparing + if cond, found := conditions.GetKVVMIMCondition(virtv1.VirtualMachineInstanceMigrationWaitingForSyncSlot, mig.Status.Conditions); found && cond.Status == corev1.ConditionTrue { + reason = vmopcondition.ReasonWaitingForSyncSlot + message = messageWaitingForSyncSlot + if cond.Message != "" { + message = cond.Message + } + } case virtv1.MigrationTargetReady, virtv1.MigrationWaitingForSync, virtv1.MigrationSynchronizing, virtv1.MigrationRunning: reason = vmopcondition.ReasonSyncing message = messageSyncingSourceAndTarget @@ -624,6 +633,8 @@ func (h LifecycleHandler) calculateMigrationProgress( return progressTargetScheduling case vmopcondition.ReasonTargetPreparing: return progressTargetPreparing + case vmopcondition.ReasonWaitingForSyncSlot: + return progressWaitingForSyncSlot case vmopcondition.ReasonTargetDiskError: return progressTargetPreparing case vmopcondition.ReasonSyncing, vmopcondition.ReasonNotConverging: diff --git a/images/virtualization-artifact/pkg/livemigration/migration_configuration.go b/images/virtualization-artifact/pkg/livemigration/migration_configuration.go index 1b6618d0b9..351ef196bd 100644 --- a/images/virtualization-artifact/pkg/livemigration/migration_configuration.go +++ b/images/virtualization-artifact/pkg/livemigration/migration_configuration.go @@ -31,6 +31,7 @@ import ( const ( ParallelOutboundMigrationsPerNodeDefault uint32 = 2 + ParallelSyncMigrationsPerNodeDefault uint32 = 1 ParallelMigrationsPerClusterDefault uint32 = 5 BandwidthPerMigrationDefault = "0Mi" NodeDrainTaintDefaultKey string = "kubevirt.io/drain" @@ -52,6 +53,13 @@ func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt) if kvconfig.Spec.Configuration.MigrationConfiguration != nil && kvconfig.Spec.Configuration.MigrationConfiguration.ParallelOutboundMigrationsPerNode != nil { parallelOutboundMigrationsPerNode = *kvconfig.Spec.Configuration.MigrationConfiguration.ParallelOutboundMigrationsPerNode } + parallelSyncMigrationsPerNode := ParallelSyncMigrationsPerNodeDefault + if kvconfig.Spec.Configuration.MigrationConfiguration != nil && kvconfig.Spec.Configuration.MigrationConfiguration.ParallelSyncMigrationsPerNode != nil { + parallelSyncMigrationsPerNode = *kvconfig.Spec.Configuration.MigrationConfiguration.ParallelSyncMigrationsPerNode + } + if parallelSyncMigrationsPerNode > parallelOutboundMigrationsPerNode { + parallelSyncMigrationsPerNode = parallelOutboundMigrationsPerNode + } // Reuse default value of BandwidthPerNode as bandwidthPerMigration. bandwidthPerMigration := resource.MustParse(BandwidthPerMigrationDefault) if kvconfig.Spec.Configuration.MigrationConfiguration != nil && kvconfig.Spec.Configuration.MigrationConfiguration.BandwidthPerMigration != nil { @@ -73,6 +81,7 @@ func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt) return &virtv1.MigrationConfiguration{ ParallelMigrationsPerCluster: ¶llelMigrationsPerCluster, ParallelOutboundMigrationsPerNode: ¶llelOutboundMigrationsPerNode, + ParallelSyncMigrationsPerNode: ¶llelSyncMigrationsPerNode, NodeDrainTaintKey: &nodeDrainTaintDefaultKey, BandwidthPerMigration: &bandwidthPerMigration, ProgressTimeout: &progressTimeout, diff --git a/images/virtualization-artifact/pkg/livemigration/migration_configuration_test.go b/images/virtualization-artifact/pkg/livemigration/migration_configuration_test.go new file mode 100644 index 0000000000..0004de7ca3 --- /dev/null +++ b/images/virtualization-artifact/pkg/livemigration/migration_configuration_test.go @@ -0,0 +1,68 @@ +/* +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 livemigration + +import ( + "testing" + + "github.com/stretchr/testify/require" + "k8s.io/utils/ptr" + virtv1 "kubevirt.io/api/core/v1" +) + +func TestNewMigrationConfiguration_ParallelSyncDefault(t *testing.T) { + kv := virtv1.KubeVirt{} + cfg := NewMigrationConfiguration(false, kv) + + require.NotNil(t, cfg.ParallelOutboundMigrationsPerNode) + require.Equal(t, ParallelOutboundMigrationsPerNodeDefault, *cfg.ParallelOutboundMigrationsPerNode) + require.NotNil(t, cfg.ParallelSyncMigrationsPerNode) + require.Equal(t, ParallelSyncMigrationsPerNodeDefault, *cfg.ParallelSyncMigrationsPerNode) +} + +func TestNewMigrationConfiguration_ParallelSyncPassthrough(t *testing.T) { + kv := virtv1.KubeVirt{ + Spec: virtv1.KubeVirtSpec{ + Configuration: virtv1.KubeVirtConfiguration{ + MigrationConfiguration: &virtv1.MigrationConfiguration{ + ParallelOutboundMigrationsPerNode: ptr.To[uint32](4), + ParallelSyncMigrationsPerNode: ptr.To[uint32](2), + }, + }, + }, + } + cfg := NewMigrationConfiguration(false, kv) + require.Equal(t, uint32(4), *cfg.ParallelOutboundMigrationsPerNode) + require.Equal(t, uint32(2), *cfg.ParallelSyncMigrationsPerNode) +} + +func TestNewMigrationConfiguration_ParallelSyncClampedToOutbound(t *testing.T) { + kv := virtv1.KubeVirt{ + Spec: virtv1.KubeVirtSpec{ + Configuration: virtv1.KubeVirtConfiguration{ + MigrationConfiguration: &virtv1.MigrationConfiguration{ + ParallelOutboundMigrationsPerNode: ptr.To[uint32](1), + ParallelSyncMigrationsPerNode: ptr.To[uint32](5), + }, + }, + }, + } + cfg := NewMigrationConfiguration(false, kv) + require.Equal(t, uint32(1), *cfg.ParallelOutboundMigrationsPerNode) + require.Equal(t, uint32(1), *cfg.ParallelSyncMigrationsPerNode, + "sync cap must be clamped to outbound cap") +} diff --git a/openapi/values.yaml b/openapi/values.yaml index c2a06fd9b4..7c4dc6fa07 100644 --- a/openapi/values.yaml +++ b/openapi/values.yaml @@ -139,6 +139,8 @@ properties: type: integer parallelOutboundMigrationsPerNode: type: integer + parallelSyncMigrationsPerNode: + type: integer progressTimeout: type: integer disableTLS: diff --git a/templates/kubevirt/_kubevirt_helpers.tpl b/templates/kubevirt/_kubevirt_helpers.tpl index 942ffb14aa..cdb08781df 100644 --- a/templates/kubevirt/_kubevirt_helpers.tpl +++ b/templates/kubevirt/_kubevirt_helpers.tpl @@ -98,6 +98,10 @@ spec: {{- .Values.virtualization.internal | dig "virtConfig" "parallelOutboundMigrationsPerNode" 2 -}} {{- end -}} +{{- define "kubevirt.parallel_sync_migrations_per_node" -}} +{{- .Values.virtualization.internal | dig "virtConfig" "parallelSyncMigrationsPerNode" 1 -}} +{{- end -}} + {{- define "kubevirt.progress_timeout" -}} {{- .Values.virtualization.internal | dig "virtConfig" "progressTimeout" 150 -}} {{- end -}} @@ -112,5 +116,6 @@ completionTimeoutPerGiB: {{ include "kubevirt.completion_timeout_per_gib" . }} disableTLS: {{ include "kubevirt.disable_tls" . }} parallelMigrationsPerCluster: {{ include "kubevirt.parallel_migrations_per_cluster" . }} parallelOutboundMigrationsPerNode: {{ include "kubevirt.parallel_outbound_migrations_per_node" . }} +parallelSyncMigrationsPerNode: {{ include "kubevirt.parallel_sync_migrations_per_node" . }} progressTimeout: {{ include "kubevirt.progress_timeout" . }} {{- end -}}