Skip to content

Commit 5630bc9

Browse files
committed
wip
Signed-off-by: Daniil Loktev <[email protected]>
1 parent 680b52b commit 5630bc9

File tree

3 files changed

+6
-183
lines changed

3 files changed

+6
-183
lines changed

images/virtualization-artifact/pkg/controller/vmop/migration/internal/handler/lifecycle.go

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
"github.com/deckhouse/virtualization-controller/pkg/common/object"
3131
commonvmop "github.com/deckhouse/virtualization-controller/pkg/common/vmop"
3232
"github.com/deckhouse/virtualization-controller/pkg/controller/conditions"
33-
"github.com/deckhouse/virtualization-controller/pkg/controller/indexer"
3433
"github.com/deckhouse/virtualization-controller/pkg/controller/vmop/migration/internal/service"
3534
genericservice "github.com/deckhouse/virtualization-controller/pkg/controller/vmop/service"
3635
"github.com/deckhouse/virtualization-controller/pkg/eventrecord"
@@ -189,23 +188,6 @@ func (h LifecycleHandler) Handle(ctx context.Context, vmop *v1alpha2.VirtualMach
189188
return reconcile.Result{}, nil
190189
}
191190

192-
// 6.3 Fail if attached vmbdas are not shared.
193-
attachedRWOHotplugDisks, err := h.areAnyRWOHotplugDisks(ctx, vm)
194-
if err != nil {
195-
return reconcile.Result{}, err
196-
}
197-
if attachedRWOHotplugDisks {
198-
vmop.Status.Phase = v1alpha2.VMOPPhaseFailed
199-
h.recorder.Event(vmop, corev1.EventTypeWarning, v1alpha2.ReasonErrVMOPFailed, "Hotplug disks are not shared. Cannot be migrated.")
200-
conditions.SetCondition(
201-
completedCond.
202-
Reason(vmopcondition.ReasonHotplugDisksNotShared).
203-
Status(metav1.ConditionFalse).
204-
Message("Hotplug disks are not shared. Cannot be migrated."),
205-
&vmop.Status.Conditions)
206-
return reconcile.Result{}, nil
207-
}
208-
209191
// 7. Check if the vm is migratable.
210192
if !h.canExecute(vmop, vm) {
211193
return reconcile.Result{}, nil
@@ -344,51 +326,6 @@ func (h LifecycleHandler) isKubeVirtMigrationRejectedDueToQuota(ctx context.Cont
344326
return false, nil
345327
}
346328

347-
func (h LifecycleHandler) areAnyRWOHotplugDisks(ctx context.Context, vm *v1alpha2.VirtualMachine) (bool, error) {
348-
vmbdaList := &v1alpha2.VirtualMachineBlockDeviceAttachmentList{}
349-
err := h.client.List(ctx, vmbdaList, client.InNamespace(vm.Namespace), &client.MatchingFields{
350-
indexer.IndexFieldVMBDAByVM: vm.Name,
351-
})
352-
if err != nil {
353-
return false, err
354-
}
355-
356-
var vmbdas []*v1alpha2.VirtualMachineBlockDeviceAttachment
357-
for _, vmbda := range vmbdaList.Items {
358-
if vmbda.Spec.BlockDeviceRef.Kind != v1alpha2.VMBDAObjectRefKindVirtualDisk {
359-
continue
360-
}
361-
vmbdas = append(vmbdas, &vmbda)
362-
}
363-
364-
for _, vmbda := range vmbdas {
365-
vd := &v1alpha2.VirtualDisk{}
366-
err = h.client.Get(ctx, client.ObjectKey{Namespace: vmbda.Namespace, Name: vmbda.Spec.BlockDeviceRef.Name}, vd)
367-
if err != nil {
368-
return false, err
369-
}
370-
371-
pvc := &corev1.PersistentVolumeClaim{}
372-
err = h.client.Get(ctx, client.ObjectKey{Namespace: vd.Namespace, Name: vd.Status.Target.PersistentVolumeClaim}, pvc)
373-
if err != nil {
374-
return false, err
375-
}
376-
377-
isRWX := false
378-
for _, mode := range pvc.Status.AccessModes {
379-
if mode == corev1.ReadWriteMany {
380-
isRWX = true
381-
break
382-
}
383-
}
384-
if !isRWX {
385-
return true, nil
386-
}
387-
}
388-
389-
return false, nil
390-
}
391-
392329
func (h LifecycleHandler) otherMigrationsAreInProgress(ctx context.Context, vmop *v1alpha2.VirtualMachineOperation) (bool, error) {
393330
migList := &virtv1.VirtualMachineInstanceMigrationList{}
394331
err := h.client.List(ctx, migList, client.InNamespace(vmop.GetNamespace()))

images/virtualization-artifact/pkg/controller/vmop/vmop_webhook.go

Lines changed: 1 addition & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,11 @@ package vmop
1818

1919
import (
2020
"context"
21-
"errors"
22-
"fmt"
2321

24-
corev1 "k8s.io/api/core/v1"
25-
"k8s.io/apimachinery/pkg/types"
2622
"sigs.k8s.io/controller-runtime/pkg/client"
2723
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
2824

2925
"github.com/deckhouse/deckhouse/pkg/log"
30-
"github.com/deckhouse/virtualization-controller/pkg/common/object"
3126
"github.com/deckhouse/virtualization-controller/pkg/controller/validator"
3227
"github.com/deckhouse/virtualization/api/core/v1alpha2"
3328
)
@@ -36,115 +31,7 @@ func NewValidator(c client.Client, log *log.Logger) admission.CustomValidator {
3631
return validator.NewValidator[*v1alpha2.VirtualMachineOperation](log.
3732
With("controller", "vmop-controller").
3833
With("webhook", "validation"),
39-
).WithCreateValidators(&deprecateMigrateValidator{}, NewLocalVirtualDiskValidator(c))
40-
}
41-
42-
type LocalVirtualDiskValidator struct {
43-
client client.Client
44-
}
45-
46-
func NewLocalVirtualDiskValidator(client client.Client) *LocalVirtualDiskValidator {
47-
return &LocalVirtualDiskValidator{client: client}
48-
}
49-
50-
func (v *LocalVirtualDiskValidator) ValidateCreate(ctx context.Context, vmop *v1alpha2.VirtualMachineOperation) (admission.Warnings, error) {
51-
if vmop.Spec.Type != v1alpha2.VMOPTypeEvict && vmop.Spec.Type != v1alpha2.VMOPTypeMigrate {
52-
return nil, nil
53-
}
54-
55-
vm, err := object.FetchObject(ctx, types.NamespacedName{
56-
Namespace: vmop.Namespace,
57-
Name: vmop.Spec.VirtualMachine,
58-
}, v.client, &v1alpha2.VirtualMachine{})
59-
if err != nil {
60-
return nil, fmt.Errorf("failed to fetch virtual machine %s: %w", vmop.Spec.VirtualMachine, err)
61-
}
62-
63-
if vm == nil {
64-
return nil, nil
65-
}
66-
67-
var hasHotplugs bool
68-
var hasRWO bool
69-
70-
for _, bdRef := range vm.Status.BlockDeviceRefs {
71-
if bdRef.Hotplugged {
72-
hasHotplugs = true
73-
}
74-
75-
switch bdRef.Kind {
76-
case v1alpha2.VirtualDiskKind:
77-
var vd *v1alpha2.VirtualDisk
78-
vd, err = object.FetchObject(ctx, types.NamespacedName{
79-
Namespace: vm.Namespace,
80-
Name: bdRef.Name,
81-
}, v.client, &v1alpha2.VirtualDisk{})
82-
if err != nil {
83-
return nil, fmt.Errorf("failed to fetch virtual disk %s: %w", bdRef.Name, err)
84-
}
85-
86-
if vd == nil || vd.Status.Target.PersistentVolumeClaim == "" {
87-
return nil, nil
88-
}
89-
90-
var isRWO bool
91-
isRWO, err = v.isRWOPersistentVolumeClaim(ctx, vd.Status.Target.PersistentVolumeClaim, vm.Namespace)
92-
if err != nil {
93-
return nil, err
94-
}
95-
96-
hasRWO = hasRWO || isRWO
97-
case v1alpha2.VirtualImageKind:
98-
var vi *v1alpha2.VirtualImage
99-
vi, err = object.FetchObject(ctx, types.NamespacedName{
100-
Namespace: vm.Namespace,
101-
Name: bdRef.Name,
102-
}, v.client, &v1alpha2.VirtualImage{})
103-
if err != nil {
104-
return nil, fmt.Errorf("failed to fetch virtual image %s: %w", bdRef.Name, err)
105-
}
106-
107-
if vi == nil || vi.Status.Target.PersistentVolumeClaim == "" {
108-
return nil, nil
109-
}
110-
111-
var isRWO bool
112-
isRWO, err = v.isRWOPersistentVolumeClaim(ctx, vi.Status.Target.PersistentVolumeClaim, vm.Namespace)
113-
if err != nil {
114-
return nil, err
115-
}
116-
117-
hasRWO = hasRWO || isRWO
118-
}
119-
}
120-
121-
if hasRWO && hasHotplugs {
122-
return nil, errors.New("for now, migration of the rwo virtual disk is not allowed if the virtual machine has hot-plugged block devices")
123-
}
124-
125-
return nil, nil
126-
}
127-
128-
func (v *LocalVirtualDiskValidator) isRWOPersistentVolumeClaim(ctx context.Context, pvcName, pvcNamespace string) (bool, error) {
129-
pvc, err := object.FetchObject(ctx, types.NamespacedName{
130-
Namespace: pvcNamespace,
131-
Name: pvcName,
132-
}, v.client, &corev1.PersistentVolumeClaim{})
133-
if err != nil {
134-
return false, fmt.Errorf("failed to fetch pvc %s: %w", pvcName, err)
135-
}
136-
137-
if pvc == nil {
138-
return false, nil
139-
}
140-
141-
for _, mode := range pvc.Status.AccessModes {
142-
if mode == corev1.ReadWriteOnce {
143-
return true, nil
144-
}
145-
}
146-
147-
return false, nil
34+
).WithCreateValidators(&deprecateMigrateValidator{})
14835
}
14936

15037
type deprecateMigrateValidator struct{}

test/e2e/vm/volume_migration_local_disks.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ var _ = Describe("LocalVirtualDiskMigration", Ordered, ContinueOnFailure, func()
438438
})
439439
})
440440

441-
It("should be failed with RWO VMBDA", func() {
441+
It("should succeed with hotplugged RWO disk", func() {
442442
ns := f.Namespace().Name
443443

444444
vm, vds := localMigrationRootAndAdditionalBuild()
@@ -477,16 +477,15 @@ var _ = Describe("LocalVirtualDiskMigration", Ordered, ContinueOnFailure, func()
477477
By("Starting migrations for virtual machines")
478478
util.MigrateVirtualMachine(f, vm, vmopbuilder.WithName(vmopName))
479479

480-
By("Waiting for migration failed")
480+
By("Waiting for migration to complete")
481481
Eventually(func(g Gomega) {
482482
vmop, err := f.VirtClient().VirtualMachineOperations(ns).Get(context.Background(), vmopName, metav1.GetOptions{})
483483
g.Expect(err).NotTo(HaveOccurred())
484484

485-
g.Expect(vmop.Status.Phase).To(Equal(v1alpha2.VMOPPhaseFailed))
485+
g.Expect(vmop.Status.Phase).To(Equal(v1alpha2.VMOPPhaseCompleted))
486486
completed, _ := conditions.GetCondition(vmopcondition.TypeCompleted, vmop.Status.Conditions)
487-
g.Expect(completed.Status).To(Equal(metav1.ConditionFalse))
488-
g.Expect(completed.Reason).To(Equal(vmopcondition.ReasonHotplugDisksNotShared.String()))
489-
}).WithTimeout(framework.MiddleTimeout).WithPolling(time.Second).Should(Succeed())
487+
g.Expect(completed.Status).To(Equal(metav1.ConditionTrue))
488+
}).WithTimeout(framework.LongTimeout).WithPolling(time.Second).Should(Succeed())
490489
})
491490
})
492491

0 commit comments

Comments
 (0)