Skip to content

Commit 1ca6d32

Browse files
fix(vm): fix live migration with image hotplug (#1041)
fix live migration with image hotplug --------- Signed-off-by: Yaroslav Borbat <yaroslav.borbat@flant.com> Co-authored-by: Ivan Mikheykin <ivan.mikheykin@flant.com>
1 parent b6ced4e commit 1ca6d32

2 files changed

Lines changed: 29 additions & 19 deletions

File tree

images/virtualization-artifact/pkg/controller/livemigration/live_migration_reconciler.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"fmt"
2222

23+
"k8s.io/apimachinery/pkg/types"
2324
virtv1 "kubevirt.io/api/core/v1"
2425
"sigs.k8s.io/controller-runtime/pkg/client"
2526
"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -88,15 +89,23 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco
8889
return h.Handle(ctx, kvvmi.Changed())
8990
})
9091
rec.SetResourceUpdater(func(ctx context.Context) error {
91-
if livemigration.IsMigrationConfigurationChanged(kvvmi.Current(), kvvmi.Changed()) {
92-
// Directly update kvvmi and not use kvvmi.Update as kvvmi status is a regular field, not a subresource.
92+
93+
patchBytes, err := livemigration.GenerateMigrationConfigurationPatch(kvvmi.Current(), kvvmi.Changed())
94+
if err != nil {
95+
return err
96+
}
97+
98+
if patchBytes != nil {
9399
log.Debug("About to update changed kvvmi",
94100
"changed.migration.configuration", livemigration.DumpKVVMIMigrationConfiguration(kvvmi.Changed()),
95101
"current.migration.configuration", livemigration.DumpKVVMIMigrationConfiguration(kvvmi.Current()),
96102
)
97-
if err := r.client.Update(ctx, kvvmi.Changed()); err != nil {
98-
return fmt.Errorf("error updating status subresource: %w", err)
103+
104+
jsonPatch := client.RawPatch(types.JSONPatchType, patchBytes)
105+
if err := r.client.Patch(ctx, kvvmi.Current(), jsonPatch); err != nil {
106+
return fmt.Errorf("error patching status field: %w", err)
99107
}
108+
100109
return nil
101110
}
102111

images/virtualization-artifact/pkg/livemigration/migration_configuration.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ package livemigration
1919
import (
2020
"encoding/json"
2121
"fmt"
22-
"reflect"
2322

23+
"k8s.io/apimachinery/pkg/api/equality"
2424
"k8s.io/apimachinery/pkg/api/resource"
2525
virtv1 "kubevirt.io/api/core/v1"
26+
27+
"github.com/deckhouse/virtualization-controller/pkg/common/patch"
2628
)
2729

2830
// Live migration defaults from kubevirt
@@ -93,22 +95,21 @@ func DumpKVVMIMigrationConfiguration(kvvmi *virtv1.VirtualMachineInstance) strin
9395
return string(out)
9496
}
9597

96-
// IsMigrationConfigurationChanged detects if MigrationConfiguration was changed.
97-
func IsMigrationConfigurationChanged(current, changed *virtv1.VirtualMachineInstance) bool {
98-
// true if migrationConfiguration was added.
99-
if current.Status.MigrationState != nil && current.Status.MigrationState.MigrationConfiguration == nil &&
100-
changed.Status.MigrationState != nil && changed.Status.MigrationState.MigrationConfiguration != nil {
101-
return true
98+
func GenerateMigrationConfigurationPatch(current, changed *virtv1.VirtualMachineInstance) ([]byte, error) {
99+
if current.Status.MigrationState == nil || changed.Status.MigrationState == nil {
100+
return nil, nil
101+
}
102+
currentConf := current.Status.MigrationState.MigrationConfiguration
103+
changedConf := changed.Status.MigrationState.MigrationConfiguration
104+
105+
if equality.Semantic.DeepEqual(currentConf, changedConf) {
106+
return nil, nil
102107
}
103108

104-
// Compare MigrationConfiguration. Handler may change options.
105-
if current.Status.MigrationState != nil && current.Status.MigrationState.MigrationConfiguration != nil &&
106-
changed.Status.MigrationState != nil && changed.Status.MigrationState.MigrationConfiguration != nil {
107-
return !reflect.DeepEqual(
108-
current.Status.MigrationState.MigrationConfiguration,
109-
changed.Status.MigrationState.MigrationConfiguration,
110-
)
109+
op := patch.PatchReplaceOp
110+
if currentConf == nil {
111+
op = patch.PatchAddOp
111112
}
112113

113-
return false
114+
return patch.NewJsonPatch(patch.NewJsonPatchOperation(op, "/status/migrationState/migrationConfiguration", changedConf)).Bytes()
114115
}

0 commit comments

Comments
 (0)