Skip to content

Commit

Permalink
utils: Add GenerateKubeVirtGroupVersionKind
Browse files Browse the repository at this point in the history
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 closed but often cited issue:

Object's TypeMeta is empty
kubernetes/client-go#413

Signed-off-by: Lee Yarwood <lyarwood@redhat.com>
  • Loading branch information
lyarwood committed Oct 27, 2022
1 parent 02e06d7 commit e076dfd
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 17 deletions.
1 change: 1 addition & 0 deletions pkg/instancetype/BUILD.bazel
Expand Up @@ -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",
Expand Down
17 changes: 8 additions & 9 deletions pkg/instancetype/instancetype.go
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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
Expand All @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/storage/snapshot/BUILD.bazel
Expand Up @@ -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",
Expand Down
16 changes: 9 additions & 7 deletions pkg/storage/snapshot/source.go
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/util/BUILD.bazel
Expand Up @@ -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",
],
)
16 changes: 16 additions & 0 deletions pkg/util/util.go
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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
}

0 comments on commit e076dfd

Please sign in to comment.