diff --git a/pkg/instancetype/BUILD.bazel b/pkg/instancetype/BUILD.bazel index a84e0518f01a..282c6f6f8dba 100644 --- a/pkg/instancetype/BUILD.bazel +++ b/pkg/instancetype/BUILD.bazel @@ -9,6 +9,7 @@ go_library( importpath = "kubevirt.io/kubevirt/pkg/instancetype", visibility = ["//visibility:public"], deps = [ + "//pkg/util:go_default_library", "//pkg/util/types:go_default_library", "//staging/src/kubevirt.io/api/core/v1:go_default_library", "//staging/src/kubevirt.io/api/instancetype:go_default_library", diff --git a/pkg/instancetype/instancetype.go b/pkg/instancetype/instancetype.go index e06310c32bbc..ad3f3f32766c 100644 --- a/pkg/instancetype/instancetype.go +++ b/pkg/instancetype/instancetype.go @@ -23,6 +23,7 @@ import ( "kubevirt.io/client-go/kubecli" "kubevirt.io/client-go/log" + utils "kubevirt.io/kubevirt/pkg/util" utiltypes "kubevirt.io/kubevirt/pkg/util/types" ) @@ -60,17 +61,15 @@ func GetRevisionName(vmName, resourceName string, resourceUID types.UID, resourc } func CreateControllerRevision(vm *virtv1.VirtualMachine, object runtime.Object) (*appsv1.ControllerRevision, error) { - objCopy := object.DeepCopyObject() - - // TypeMeta may be missing, so set it here. - gvks, _, err := generatedscheme.Scheme.ObjectKinds(objCopy) + obj, err := utils.GenerateKubeVirtGroupVersionKind(object) if err != nil { - // This is a programmer's error and should not happen. - return nil, fmt.Errorf("could not get GroupVersionKind for object: %w", err) + return nil, err + } + metaObj, ok := obj.(metav1.Object) + if !ok { + return nil, fmt.Errorf("Unexpected object format returned from GenerateKubeVirtGroupVersionKind") } - objCopy.GetObjectKind().SetGroupVersionKind(gvks[0]) - metaObj := objCopy.(metav1.Object) revisionName := GetRevisionName(vm.Name, metaObj.GetName(), metaObj.GetUID(), metaObj.GetGeneration()) // Removing unnecessary metadata @@ -87,7 +86,7 @@ func CreateControllerRevision(vm *virtv1.VirtualMachine, object runtime.Object) OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(vm, virtv1.VirtualMachineGroupVersionKind)}, }, Data: runtime.RawExtension{ - Object: objCopy, + Object: obj, }, }, nil } diff --git a/pkg/storage/snapshot/BUILD.bazel b/pkg/storage/snapshot/BUILD.bazel index 1903a8c00bfe..b41f03882def 100644 --- a/pkg/storage/snapshot/BUILD.bazel +++ b/pkg/storage/snapshot/BUILD.bazel @@ -15,12 +15,12 @@ go_library( deps = [ "//pkg/controller:go_default_library", "//pkg/storage/types:go_default_library", + "//pkg/util:go_default_library", "//pkg/util/status:go_default_library", "//pkg/virt-controller/watch/util:go_default_library", "//pkg/virt-launcher/virtwrap/api:go_default_library", "//staging/src/kubevirt.io/api/core/v1:go_default_library", "//staging/src/kubevirt.io/api/snapshot/v1alpha1:go_default_library", - "//staging/src/kubevirt.io/client-go/generated/kubevirt/clientset/versioned/scheme:go_default_library", "//staging/src/kubevirt.io/client-go/kubecli:go_default_library", "//staging/src/kubevirt.io/client-go/log:go_default_library", "//vendor/github.com/evanphx/json-patch:go_default_library", diff --git a/pkg/storage/snapshot/source.go b/pkg/storage/snapshot/source.go index 3706bffb75ad..f2dfc3decf2d 100644 --- a/pkg/storage/snapshot/source.go +++ b/pkg/storage/snapshot/source.go @@ -35,11 +35,11 @@ import ( kubevirtv1 "kubevirt.io/api/core/v1" snapshotv1 "kubevirt.io/api/snapshot/v1alpha1" - generatedscheme "kubevirt.io/client-go/generated/kubevirt/clientset/versioned/scheme" "kubevirt.io/client-go/log" "kubevirt.io/kubevirt/pkg/controller" storagetypes "kubevirt.io/kubevirt/pkg/storage/types" + utils "kubevirt.io/kubevirt/pkg/util" watchutil "kubevirt.io/kubevirt/pkg/virt-controller/watch/util" launcherapi "kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/api" ) @@ -212,14 +212,16 @@ func (s *vmSnapshotSource) captureInstancetypeControllerRevision(namespace, revi // We strip out the source VM name from the CR name and replace it with the snapshot name snapshotCR.Name = s.snapshot.Name + strings.ReplaceAll(existingCR.Name, s.snapshot.Spec.Source.Name, "") - // TODO - share with pkg/instancetype somewhere - snapshotCopy := s.snapshot.DeepCopy() - gvks, _, err := generatedscheme.Scheme.ObjectKinds(snapshotCopy) + // Ensure GVK is set before we attempt to create the controller OwnerReference below + obj, err := utils.GenerateKubeVirtGroupVersionKind(s.snapshot) if err != nil { - return "", fmt.Errorf("could not get GroupVersionKind for object: %w", err) + return "", err + } + snapshot, ok := obj.(*snapshotv1.VirtualMachineSnapshot) + if !ok { + return "", fmt.Errorf("Unexpected object format returned from GenerateKubeVirtGroupVersionKind") } - snapshotCopy.GetObjectKind().SetGroupVersionKind(gvks[0]) - snapshotCR.OwnerReferences = []metav1.OwnerReference{*metav1.NewControllerRef(snapshotCopy, snapshotCopy.GroupVersionKind())} + snapshotCR.OwnerReferences = []metav1.OwnerReference{*metav1.NewControllerRef(snapshot, snapshot.GroupVersionKind())} snapshotCR, err = s.controller.Client.AppsV1().ControllerRevisions(s.snapshot.Namespace).Create(context.Background(), snapshotCR, metav1.CreateOptions{}) if err != nil && !errors.IsAlreadyExists(err) { diff --git a/pkg/util/BUILD.bazel b/pkg/util/BUILD.bazel index 91fce18fe783..baea80ecd1a9 100644 --- a/pkg/util/BUILD.bazel +++ b/pkg/util/BUILD.bazel @@ -10,7 +10,9 @@ go_library( visibility = ["//visibility:public"], deps = [ "//staging/src/kubevirt.io/api/core/v1:go_default_library", + "//staging/src/kubevirt.io/client-go/generated/kubevirt/clientset/versioned/scheme:go_default_library", "//staging/src/kubevirt.io/client-go/log:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", ], ) diff --git a/pkg/util/util.go b/pkg/util/util.go index 146a6ac4649a..6cf8ad23e994 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -9,8 +9,10 @@ import ( "strings" "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/runtime" v1 "kubevirt.io/api/core/v1" + generatedscheme "kubevirt.io/client-go/generated/kubevirt/clientset/versioned/scheme" "kubevirt.io/client-go/log" ) @@ -258,3 +260,17 @@ func GenerateSecureRandomString(n int) (string, error) { return string(ret), nil } + +// GenerateKubeVirtGroupVersionKind ensures a provided object registered with KubeVirts generated schema +// has GVK set correctly. This is required as client-go continues to return objects without +// TypeMeta set as set out in the following issue: https://github.com/kubernetes/client-go/issues/413 +func GenerateKubeVirtGroupVersionKind(obj runtime.Object) (runtime.Object, error) { + objCopy := obj.DeepCopyObject() + gvks, _, err := generatedscheme.Scheme.ObjectKinds(objCopy) + if err != nil { + return nil, fmt.Errorf("could not get GroupVersionKind for object: %w", err) + } + objCopy.GetObjectKind().SetGroupVersionKind(gvks[0]) + + return objCopy, nil +}