From be1a28bed9fa4256f99d7ef423f0ad9f7e165ab3 Mon Sep 17 00:00:00 2001 From: Sunil Arora Date: Tue, 17 Apr 2018 15:20:17 -0700 Subject: [PATCH] fixed infinite loop in watchControllerOf API This changes fixes a bug where generic controller can get stuck in inifite loop while resolving parent object for a generated object. It can happen where we encounter an object with no owner reference while walking up the ancestor tree and lookup paths are not yet done. --- pkg/controller/eventhandlers/eventhandlers.go | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/pkg/controller/eventhandlers/eventhandlers.go b/pkg/controller/eventhandlers/eventhandlers.go index 4b5d1b2e928..4716dcfad6c 100644 --- a/pkg/controller/eventhandlers/eventhandlers.go +++ b/pkg/controller/eventhandlers/eventhandlers.go @@ -127,29 +127,32 @@ func (m MapToController) Map(obj interface{}) string { o := object for len(m.Path) > 0 { // Get the owner reference - if ownerRef := metav1.GetControllerOf(o); ownerRef != nil { - // Resolve the owner object and check if the UID of the looked up object matches the reference. - owner, err := m.Path[0](types.ReconcileKey{Name: ownerRef.Name, Namespace: o.GetNamespace()}) - if err != nil || owner == nil { - glog.V(2).Infof("Could not lookup owner %v %v", owner, err) - return "" - } - var ownerObject metav1.Object - if ownerObject, ok = owner.(metav1.Object); !ok { - glog.V(2).Infof("No ObjectMeta for owner %v %v", owner, err) - return "" - } - if ownerObject.GetUID() != ownerRef.UID { - return "" - } + ownerRef := metav1.GetControllerOf(o) + if ownerRef == nil { + glog.V(2).Infof("object %v does not have any owner reference", o) + return "" + } + // Resolve the owner object and check if the UID of the looked up object matches the reference. + owner, err := m.Path[0](types.ReconcileKey{Name: ownerRef.Name, Namespace: o.GetNamespace()}) + if err != nil || owner == nil { + glog.V(2).Infof("Could not lookup owner %v %v", owner, err) + return "" + } + var ownerObject metav1.Object + if ownerObject, ok = owner.(metav1.Object); !ok { + glog.V(2).Infof("No ObjectMeta for owner %v %v", owner, err) + return "" + } + if ownerObject.GetUID() != ownerRef.UID { + return "" + } - // Pop the path element or return the value - if len(m.Path) > 1 { - o = ownerObject - m.Path = m.Path[1:] - } else { - return object.GetNamespace() + "/" + ownerRef.Name - } + // Pop the path element or return the value + if len(m.Path) > 1 { + o = ownerObject + m.Path = m.Path[1:] + } else { + return object.GetNamespace() + "/" + ownerRef.Name } } return ""